tor/src/lib/crypt_ops/crypto.c

509 lines
14 KiB
C
Raw Normal View History

/* Copyright (c) 2001, Matej Pfajfar.
2006-02-09 06:46:49 +01:00
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
2018-06-20 14:13:28 +02:00
* Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
2004-05-10 05:53:24 +02:00
/**
* \file crypto.c
* \brief Wrapper functions to present a consistent interface to
* public-key and symmetric cryptography operations from OpenSSL and
* other places.
2004-05-10 05:53:24 +02:00
**/
#include "orconfig.h"
#ifdef _WIN32
#include <winsock2.h>
#include <windows.h>
#include <wincrypt.h>
2009-05-27 23:55:51 +02:00
/* Windows defines this; so does OpenSSL 0.9.8h and later. We don't actually
* use either definition. */
#undef OCSP_RESPONSE
#endif /* defined(_WIN32) */
#define CRYPTO_PRIVATE
2018-06-20 15:35:05 +02:00
#include "common/compat_openssl.h"
#include "common/crypto.h"
#include "common/crypto_curve25519.h"
#include "common/crypto_digest.h"
#include "common/crypto_dh.h"
#include "common/crypto_ed25519.h"
#include "common/crypto_format.h"
#include "common/crypto_rand.h"
#include "common/crypto_rsa.h"
#include "common/crypto_util.h"
DISABLE_GCC_WARNING(redundant-decls)
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/engine.h>
#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/conf.h>
#include <openssl/hmac.h>
#include <openssl/ssl.h>
ENABLE_GCC_WARNING(redundant-decls)
#if __GNUC__ && GCC_VERSION >= 402
#if GCC_VERSION >= 406
#pragma GCC diagnostic pop
#else
#pragma GCC diagnostic warning "-Wredundant-decls"
#endif
#endif /* __GNUC__ && GCC_VERSION >= 402 */
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
2018-06-20 15:35:05 +02:00
#include "common/torlog.h"
2018-06-21 18:20:52 +02:00
#include "lib/cc/torint.h"
2018-06-20 15:35:05 +02:00
#include "common/aes.h"
#include "common/util.h"
#include "common/container.h"
#include "common/compat.h"
#include "common/sandbox.h"
#include "common/util_format.h"
#include "keccak-tiny/keccak-tiny.h"
/** Boolean: has OpenSSL's crypto been initialized? */
static int crypto_early_initialized_ = 0;
2004-05-10 05:53:24 +02:00
/** Boolean: has OpenSSL's crypto been initialized? */
Rename all reserved C identifiers we defined For everything we declare that starts with _, make it end with _ instead. This is a machine-generated patch. To make it, start by getting the list of reserved identifiers using: git ls-tree -r --name-only HEAD | grep '\.[ch]$' | \ xargs ctags --c-kinds=defglmpstuvx -o - | grep '^_' | \ cut -f 1 | sort| uniq You might need gnu ctags. Then pipe the output through this script: ============================== use strict; BEGIN { print "#!/usr/bin/perl -w -i -p\n\n"; } chomp; next if ( /^__attribute__/ or /^__func__/ or /^_FILE_OFFSET_BITS/ or /^_FORTIFY_SOURCE/ or /^_GNU_SOURCE/ or /^_WIN32/ or /^_DARWIN_UNLIMITED/ or /^_FILE_OFFSET_BITS/ or /^_LARGEFILE64_SOURCE/ or /^_LFS64_LARGEFILE/ or /^__cdecl/ or /^__attribute__/ or /^__func__/ or /^_WIN32_WINNT/); my $ident = $_; my $better = $ident; $better =~ s/^_//; $better = "${better}_"; print "s/(?<![A-Za-z0-9_])$ident(?![A-Za-z0-9_])/$better/g;\n"; ============================== Then run the resulting script on all the files you want to change. (That is, all the C except that in src/ext.) The resulting script was: ============================== s/(?<![A-Za-z0-9_])_address(?![A-Za-z0-9_])/address_/g; s/(?<![A-Za-z0-9_])_aes_fill_buf(?![A-Za-z0-9_])/aes_fill_buf_/g; s/(?<![A-Za-z0-9_])_AllowInvalid(?![A-Za-z0-9_])/AllowInvalid_/g; s/(?<![A-Za-z0-9_])_AP_CONN_STATE_MAX(?![A-Za-z0-9_])/AP_CONN_STATE_MAX_/g; s/(?<![A-Za-z0-9_])_AP_CONN_STATE_MIN(?![A-Za-z0-9_])/AP_CONN_STATE_MIN_/g; s/(?<![A-Za-z0-9_])_assert_cache_ok(?![A-Za-z0-9_])/assert_cache_ok_/g; s/(?<![A-Za-z0-9_])_A_UNKNOWN(?![A-Za-z0-9_])/A_UNKNOWN_/g; s/(?<![A-Za-z0-9_])_base(?![A-Za-z0-9_])/base_/g; s/(?<![A-Za-z0-9_])_BridgePassword_AuthDigest(?![A-Za-z0-9_])/BridgePassword_AuthDigest_/g; s/(?<![A-Za-z0-9_])_buffer_stats_compare_entries(?![A-Za-z0-9_])/buffer_stats_compare_entries_/g; s/(?<![A-Za-z0-9_])_chan_circid_entries_eq(?![A-Za-z0-9_])/chan_circid_entries_eq_/g; s/(?<![A-Za-z0-9_])_chan_circid_entry_hash(?![A-Za-z0-9_])/chan_circid_entry_hash_/g; s/(?<![A-Za-z0-9_])_check_no_tls_errors(?![A-Za-z0-9_])/check_no_tls_errors_/g; s/(?<![A-Za-z0-9_])_c_hist_compare(?![A-Za-z0-9_])/c_hist_compare_/g; s/(?<![A-Za-z0-9_])_circ(?![A-Za-z0-9_])/circ_/g; s/(?<![A-Za-z0-9_])_circuit_get_global_list(?![A-Za-z0-9_])/circuit_get_global_list_/g; s/(?<![A-Za-z0-9_])_circuit_mark_for_close(?![A-Za-z0-9_])/circuit_mark_for_close_/g; s/(?<![A-Za-z0-9_])_CIRCUIT_PURPOSE_C_MAX(?![A-Za-z0-9_])/CIRCUIT_PURPOSE_C_MAX_/g; s/(?<![A-Za-z0-9_])_CIRCUIT_PURPOSE_MAX(?![A-Za-z0-9_])/CIRCUIT_PURPOSE_MAX_/g; s/(?<![A-Za-z0-9_])_CIRCUIT_PURPOSE_MIN(?![A-Za-z0-9_])/CIRCUIT_PURPOSE_MIN_/g; s/(?<![A-Za-z0-9_])_CIRCUIT_PURPOSE_OR_MAX(?![A-Za-z0-9_])/CIRCUIT_PURPOSE_OR_MAX_/g; s/(?<![A-Za-z0-9_])_CIRCUIT_PURPOSE_OR_MIN(?![A-Za-z0-9_])/CIRCUIT_PURPOSE_OR_MIN_/g; s/(?<![A-Za-z0-9_])_cmp_int_strings(?![A-Za-z0-9_])/cmp_int_strings_/g; s/(?<![A-Za-z0-9_])_compare_cached_resolves_by_expiry(?![A-Za-z0-9_])/compare_cached_resolves_by_expiry_/g; s/(?<![A-Za-z0-9_])_compare_digests(?![A-Za-z0-9_])/compare_digests_/g; s/(?<![A-Za-z0-9_])_compare_digests256(?![A-Za-z0-9_])/compare_digests256_/g; s/(?<![A-Za-z0-9_])_compare_dir_src_ents_by_authority_id(?![A-Za-z0-9_])/compare_dir_src_ents_by_authority_id_/g; s/(?<![A-Za-z0-9_])_compare_duration_idx(?![A-Za-z0-9_])/compare_duration_idx_/g; s/(?<![A-Za-z0-9_])_compare_int(?![A-Za-z0-9_])/compare_int_/g; s/(?<![A-Za-z0-9_])_compare_networkstatus_v2_published_on(?![A-Za-z0-9_])/compare_networkstatus_v2_published_on_/g; s/(?<![A-Za-z0-9_])_compare_old_routers_by_identity(?![A-Za-z0-9_])/compare_old_routers_by_identity_/g; s/(?<![A-Za-z0-9_])_compare_orports(?![A-Za-z0-9_])/compare_orports_/g; s/(?<![A-Za-z0-9_])_compare_pairs(?![A-Za-z0-9_])/compare_pairs_/g; s/(?<![A-Za-z0-9_])_compare_routerinfo_by_id_digest(?![A-Za-z0-9_])/compare_routerinfo_by_id_digest_/g; s/(?<![A-Za-z0-9_])_compare_routerinfo_by_ip_and_bw(?![A-Za-z0-9_])/compare_routerinfo_by_ip_and_bw_/g; s/(?<![A-Za-z0-9_])_compare_signed_descriptors_by_age(?![A-Za-z0-9_])/compare_signed_descriptors_by_age_/g; s/(?<![A-Za-z0-9_])_compare_string_ptrs(?![A-Za-z0-9_])/compare_string_ptrs_/g; s/(?<![A-Za-z0-9_])_compare_strings_for_pqueue(?![A-Za-z0-9_])/compare_strings_for_pqueue_/g; s/(?<![A-Za-z0-9_])_compare_strs(?![A-Za-z0-9_])/compare_strs_/g; s/(?<![A-Za-z0-9_])_compare_tor_version_str_ptr(?![A-Za-z0-9_])/compare_tor_version_str_ptr_/g; s/(?<![A-Za-z0-9_])_compare_vote_rs(?![A-Za-z0-9_])/compare_vote_rs_/g; s/(?<![A-Za-z0-9_])_compare_votes_by_authority_id(?![A-Za-z0-9_])/compare_votes_by_authority_id_/g; s/(?<![A-Za-z0-9_])_compare_without_first_ch(?![A-Za-z0-9_])/compare_without_first_ch_/g; s/(?<![A-Za-z0-9_])_connection_free(?![A-Za-z0-9_])/connection_free_/g; s/(?<![A-Za-z0-9_])_connection_mark_and_flush(?![A-Za-z0-9_])/connection_mark_and_flush_/g; s/(?<![A-Za-z0-9_])_connection_mark_for_close(?![A-Za-z0-9_])/connection_mark_for_close_/g; s/(?<![A-Za-z0-9_])_connection_mark_unattached_ap(?![A-Za-z0-9_])/connection_mark_unattached_ap_/g; s/(?<![A-Za-z0-9_])_connection_write_to_buf_impl(?![A-Za-z0-9_])/connection_write_to_buf_impl_/g; s/(?<![A-Za-z0-9_])_ConnLimit(?![A-Za-z0-9_])/ConnLimit_/g; s/(?<![A-Za-z0-9_])_CONN_TYPE_MAX(?![A-Za-z0-9_])/CONN_TYPE_MAX_/g; s/(?<![A-Za-z0-9_])_CONN_TYPE_MIN(?![A-Za-z0-9_])/CONN_TYPE_MIN_/g; s/(?<![A-Za-z0-9_])_CONTROL_CONN_STATE_MAX(?![A-Za-z0-9_])/CONTROL_CONN_STATE_MAX_/g; s/(?<![A-Za-z0-9_])_CONTROL_CONN_STATE_MIN(?![A-Za-z0-9_])/CONTROL_CONN_STATE_MIN_/g; s/(?<![A-Za-z0-9_])_CPUWORKER_STATE_MAX(?![A-Za-z0-9_])/CPUWORKER_STATE_MAX_/g; s/(?<![A-Za-z0-9_])_CPUWORKER_STATE_MIN(?![A-Za-z0-9_])/CPUWORKER_STATE_MIN_/g; s/(?<![A-Za-z0-9_])_crypto_dh_get_dh(?![A-Za-z0-9_])/crypto_dh_get_dh_/g; s/(?<![A-Za-z0-9_])_crypto_global_initialized(?![A-Za-z0-9_])/crypto_global_initialized_/g; s/(?<![A-Za-z0-9_])_crypto_new_pk_from_rsa(?![A-Za-z0-9_])/crypto_new_pk_from_rsa_/g; s/(?<![A-Za-z0-9_])_crypto_pk_get_evp_pkey(?![A-Za-z0-9_])/crypto_pk_get_evp_pkey_/g; s/(?<![A-Za-z0-9_])_crypto_pk_get_rsa(?![A-Za-z0-9_])/crypto_pk_get_rsa_/g; s/(?<![A-Za-z0-9_])_DIR_CONN_STATE_MAX(?![A-Za-z0-9_])/DIR_CONN_STATE_MAX_/g; s/(?<![A-Za-z0-9_])_DIR_CONN_STATE_MIN(?![A-Za-z0-9_])/DIR_CONN_STATE_MIN_/g; s/(?<![A-Za-z0-9_])_DIR_PURPOSE_MAX(?![A-Za-z0-9_])/DIR_PURPOSE_MAX_/g; s/(?<![A-Za-z0-9_])_DIR_PURPOSE_MIN(?![A-Za-z0-9_])/DIR_PURPOSE_MIN_/g; s/(?<![A-Za-z0-9_])_dirreq_map_get(?![A-Za-z0-9_])/dirreq_map_get_/g; s/(?<![A-Za-z0-9_])_dirreq_map_put(?![A-Za-z0-9_])/dirreq_map_put_/g; s/(?<![A-Za-z0-9_])_dns_randfn(?![A-Za-z0-9_])/dns_randfn_/g; s/(?<![A-Za-z0-9_])_dummy(?![A-Za-z0-9_])/dummy_/g; s/(?<![A-Za-z0-9_])_edge(?![A-Za-z0-9_])/edge_/g; s/(?<![A-Za-z0-9_])_END_CIRC_REASON_MAX(?![A-Za-z0-9_])/END_CIRC_REASON_MAX_/g; s/(?<![A-Za-z0-9_])_END_CIRC_REASON_MIN(?![A-Za-z0-9_])/END_CIRC_REASON_MIN_/g; s/(?<![A-Za-z0-9_])_EOF(?![A-Za-z0-9_])/EOF_/g; s/(?<![A-Za-z0-9_])_ERR(?![A-Za-z0-9_])/ERR_/g; s/(?<![A-Za-z0-9_])_escaped_val(?![A-Za-z0-9_])/escaped_val_/g; s/(?<![A-Za-z0-9_])_evdns_log(?![A-Za-z0-9_])/evdns_log_/g; s/(?<![A-Za-z0-9_])_evdns_nameserver_add_impl(?![A-Za-z0-9_])/evdns_nameserver_add_impl_/g; s/(?<![A-Za-z0-9_])_EVENT_MAX(?![A-Za-z0-9_])/EVENT_MAX_/g; s/(?<![A-Za-z0-9_])_EVENT_MIN(?![A-Za-z0-9_])/EVENT_MIN_/g; s/(?<![A-Za-z0-9_])_ExcludeExitNodesUnion(?![A-Za-z0-9_])/ExcludeExitNodesUnion_/g; s/(?<![A-Za-z0-9_])_EXIT_CONN_STATE_MAX(?![A-Za-z0-9_])/EXIT_CONN_STATE_MAX_/g; s/(?<![A-Za-z0-9_])_EXIT_CONN_STATE_MIN(?![A-Za-z0-9_])/EXIT_CONN_STATE_MIN_/g; s/(?<![A-Za-z0-9_])_EXIT_PURPOSE_MAX(?![A-Za-z0-9_])/EXIT_PURPOSE_MAX_/g; s/(?<![A-Za-z0-9_])_EXIT_PURPOSE_MIN(?![A-Za-z0-9_])/EXIT_PURPOSE_MIN_/g; s/(?<![A-Za-z0-9_])_extrainfo_free(?![A-Za-z0-9_])/extrainfo_free_/g; s/(?<![A-Za-z0-9_])_find_by_keyword(?![A-Za-z0-9_])/find_by_keyword_/g; s/(?<![A-Za-z0-9_])_free_cached_dir(?![A-Za-z0-9_])/free_cached_dir_/g; s/(?<![A-Za-z0-9_])_free_cached_resolve(?![A-Za-z0-9_])/free_cached_resolve_/g; s/(?<![A-Za-z0-9_])_free_duplicate_routerstatus_entry(?![A-Za-z0-9_])/free_duplicate_routerstatus_entry_/g; s/(?<![A-Za-z0-9_])_free_link_history(?![A-Za-z0-9_])/free_link_history_/g; s/(?<![A-Za-z0-9_])_geoip_compare_entries(?![A-Za-z0-9_])/geoip_compare_entries_/g; s/(?<![A-Za-z0-9_])_geoip_compare_key_to_entry(?![A-Za-z0-9_])/geoip_compare_key_to_entry_/g; s/(?<![A-Za-z0-9_])_hex_decode_digit(?![A-Za-z0-9_])/hex_decode_digit_/g; s/(?<![A-Za-z0-9_])_idxplus1(?![A-Za-z0-9_])/idxplus1_/g; s/(?<![A-Za-z0-9_])__libc_enable_secure(?![A-Za-z0-9_])/_libc_enable_secure_/g; s/(?<![A-Za-z0-9_])_log_debug(?![A-Za-z0-9_])/log_debug_/g; s/(?<![A-Za-z0-9_])_log_err(?![A-Za-z0-9_])/log_err_/g; s/(?<![A-Za-z0-9_])_log_fn(?![A-Za-z0-9_])/log_fn_/g; s/(?<![A-Za-z0-9_])_log_fn_function_name(?![A-Za-z0-9_])/log_fn_function_name_/g; s/(?<![A-Za-z0-9_])_log_global_min_severity(?![A-Za-z0-9_])/log_global_min_severity_/g; s/(?<![A-Za-z0-9_])_log_info(?![A-Za-z0-9_])/log_info_/g; s/(?<![A-Za-z0-9_])_log_notice(?![A-Za-z0-9_])/log_notice_/g; s/(?<![A-Za-z0-9_])_log_prefix(?![A-Za-z0-9_])/log_prefix_/g; s/(?<![A-Za-z0-9_])_log_warn(?![A-Za-z0-9_])/log_warn_/g; s/(?<![A-Za-z0-9_])_magic(?![A-Za-z0-9_])/magic_/g; s/(?<![A-Za-z0-9_])_MALLOC_LOCK(?![A-Za-z0-9_])/MALLOC_LOCK_/g; s/(?<![A-Za-z0-9_])_MALLOC_LOCK_INIT(?![A-Za-z0-9_])/MALLOC_LOCK_INIT_/g; s/(?<![A-Za-z0-9_])_MALLOC_UNLOCK(?![A-Za-z0-9_])/MALLOC_UNLOCK_/g; s/(?<![A-Za-z0-9_])_microdesc_eq(?![A-Za-z0-9_])/microdesc_eq_/g; s/(?<![A-Za-z0-9_])_microdesc_hash(?![A-Za-z0-9_])/microdesc_hash_/g; s/(?<![A-Za-z0-9_])_MIN_TOR_TLS_ERROR_VAL(?![A-Za-z0-9_])/MIN_TOR_TLS_ERROR_VAL_/g; s/(?<![A-Za-z0-9_])_mm_free(?![A-Za-z0-9_])/mm_free_/g; s/(?<![A-Za-z0-9_])_NIL(?![A-Za-z0-9_])/NIL_/g; s/(?<![A-Za-z0-9_])_n_openssl_mutexes(?![A-Za-z0-9_])/n_openssl_mutexes_/g; s/(?<![A-Za-z0-9_])_openssl_dynlock_create_cb(?![A-Za-z0-9_])/openssl_dynlock_create_cb_/g; s/(?<![A-Za-z0-9_])_openssl_dynlock_destroy_cb(?![A-Za-z0-9_])/openssl_dynlock_destroy_cb_/g; s/(?<![A-Za-z0-9_])_openssl_dynlock_lock_cb(?![A-Za-z0-9_])/openssl_dynlock_lock_cb_/g; s/(?<![A-Za-z0-9_])_openssl_locking_cb(?![A-Za-z0-9_])/openssl_locking_cb_/g; s/(?<![A-Za-z0-9_])_openssl_mutexes(?![A-Za-z0-9_])/openssl_mutexes_/g; s/(?<![A-Za-z0-9_])_option_abbrevs(?![A-Za-z0-9_])/option_abbrevs_/g; s/(?<![A-Za-z0-9_])_option_vars(?![A-Za-z0-9_])/option_vars_/g; s/(?<![A-Za-z0-9_])_OR_CONN_STATE_MAX(?![A-Za-z0-9_])/OR_CONN_STATE_MAX_/g; s/(?<![A-Za-z0-9_])_OR_CONN_STATE_MIN(?![A-Za-z0-9_])/OR_CONN_STATE_MIN_/g; s/(?<![A-Za-z0-9_])_OutboundBindAddressIPv4(?![A-Za-z0-9_])/OutboundBindAddressIPv4_/g; s/(?<![A-Za-z0-9_])_OutboundBindAddressIPv6(?![A-Za-z0-9_])/OutboundBindAddressIPv6_/g; s/(?<![A-Za-z0-9_])_PDS_PREFER_TUNNELED_DIR_CONNS(?![A-Za-z0-9_])/PDS_PREFER_TUNNELED_DIR_CONNS_/g; s/(?<![A-Za-z0-9_])_port(?![A-Za-z0-9_])/port_/g; s/(?<![A-Za-z0-9_])__progname(?![A-Za-z0-9_])/_progname_/g; s/(?<![A-Za-z0-9_])_PublishServerDescriptor(?![A-Za-z0-9_])/PublishServerDescriptor_/g; s/(?<![A-Za-z0-9_])_remove_old_client_helper(?![A-Za-z0-9_])/remove_old_client_helper_/g; s/(?<![A-Za-z0-9_])_rend_cache_entry_free(?![A-Za-z0-9_])/rend_cache_entry_free_/g; s/(?<![A-Za-z0-9_])_routerlist_find_elt(?![A-Za-z0-9_])/routerlist_find_elt_/g; s/(?<![A-Za-z0-9_])_SafeLogging(?![A-Za-z0-9_])/SafeLogging_/g; s/(?<![A-Za-z0-9_])_SHORT_FILE_(?![A-Za-z0-9_])/SHORT_FILE__/g; s/(?<![A-Za-z0-9_])_state_abbrevs(?![A-Za-z0-9_])/state_abbrevs_/g; s/(?<![A-Za-z0-9_])_state_vars(?![A-Za-z0-9_])/state_vars_/g; s/(?<![A-Za-z0-9_])_t(?![A-Za-z0-9_])/t_/g; s/(?<![A-Za-z0-9_])_t32(?![A-Za-z0-9_])/t32_/g; s/(?<![A-Za-z0-9_])_test_op_ip6(?![A-Za-z0-9_])/test_op_ip6_/g; s/(?<![A-Za-z0-9_])_thread1_name(?![A-Za-z0-9_])/thread1_name_/g; s/(?<![A-Za-z0-9_])_thread2_name(?![A-Za-z0-9_])/thread2_name_/g; s/(?<![A-Za-z0-9_])_thread_test_func(?![A-Za-z0-9_])/thread_test_func_/g; s/(?<![A-Za-z0-9_])_thread_test_mutex(?![A-Za-z0-9_])/thread_test_mutex_/g; s/(?<![A-Za-z0-9_])_thread_test_start1(?![A-Za-z0-9_])/thread_test_start1_/g; s/(?<![A-Za-z0-9_])_thread_test_start2(?![A-Za-z0-9_])/thread_test_start2_/g; s/(?<![A-Za-z0-9_])_thread_test_strmap(?![A-Za-z0-9_])/thread_test_strmap_/g; s/(?<![A-Za-z0-9_])_tor_calloc(?![A-Za-z0-9_])/tor_calloc_/g; s/(?<![A-Za-z0-9_])_TOR_CHANNEL_INTERNAL(?![A-Za-z0-9_])/TOR_CHANNEL_INTERNAL_/g; s/(?<![A-Za-z0-9_])_TOR_CIRCUITMUX_EWMA_C(?![A-Za-z0-9_])/TOR_CIRCUITMUX_EWMA_C_/g; s/(?<![A-Za-z0-9_])_tor_free(?![A-Za-z0-9_])/tor_free_/g; s/(?<![A-Za-z0-9_])_tor_malloc(?![A-Za-z0-9_])/tor_malloc_/g; s/(?<![A-Za-z0-9_])_tor_malloc_zero(?![A-Za-z0-9_])/tor_malloc_zero_/g; s/(?<![A-Za-z0-9_])_tor_memdup(?![A-Za-z0-9_])/tor_memdup_/g; s/(?<![A-Za-z0-9_])_tor_realloc(?![A-Za-z0-9_])/tor_realloc_/g; s/(?<![A-Za-z0-9_])_tor_strdup(?![A-Za-z0-9_])/tor_strdup_/g; s/(?<![A-Za-z0-9_])_tor_strndup(?![A-Za-z0-9_])/tor_strndup_/g; s/(?<![A-Za-z0-9_])_TOR_TLS_SYSCALL(?![A-Za-z0-9_])/TOR_TLS_SYSCALL_/g; s/(?<![A-Za-z0-9_])_TOR_TLS_ZERORETURN(?![A-Za-z0-9_])/TOR_TLS_ZERORETURN_/g; s/(?<![A-Za-z0-9_])__USE_ISOC99(?![A-Za-z0-9_])/_USE_ISOC99_/g; s/(?<![A-Za-z0-9_])_UsingTestNetworkDefaults(?![A-Za-z0-9_])/UsingTestNetworkDefaults_/g; s/(?<![A-Za-z0-9_])_val(?![A-Za-z0-9_])/val_/g; s/(?<![A-Za-z0-9_])_void_for_alignment(?![A-Za-z0-9_])/void_for_alignment_/g; ==============================
2012-10-12 18:22:13 +02:00
static int crypto_global_initialized_ = 0;
#ifndef DISABLE_ENGINES
/** Log any OpenSSL engines we're using at NOTICE. */
static void
log_engine(const char *fn, ENGINE *e)
{
if (e) {
const char *name, *id;
name = ENGINE_get_name(e);
id = ENGINE_get_id(e);
log_notice(LD_CRYPTO, "Default OpenSSL engine for %s is %s [%s]",
fn, name?name:"?", id?id:"?");
} else {
log_info(LD_CRYPTO, "Using default implementation for %s", fn);
}
}
#endif /* !defined(DISABLE_ENGINES) */
#ifndef DISABLE_ENGINES
/** Try to load an engine in a shared library via fully qualified path.
*/
static ENGINE *
try_load_engine(const char *path, const char *engine)
{
ENGINE *e = ENGINE_by_id("dynamic");
if (e) {
if (!ENGINE_ctrl_cmd_string(e, "ID", engine, 0) ||
!ENGINE_ctrl_cmd_string(e, "DIR_LOAD", "2", 0) ||
!ENGINE_ctrl_cmd_string(e, "DIR_ADD", path, 0) ||
!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) {
ENGINE_free(e);
e = NULL;
}
}
return e;
}
#endif /* !defined(DISABLE_ENGINES) */
static int have_seeded_siphash = 0;
/** Set up the siphash key if we haven't already done so. */
int
crypto_init_siphash_key(void)
{
struct sipkey key;
if (have_seeded_siphash)
return 0;
crypto_rand((char*) &key, sizeof(key));
siphash_set_global_key(&key);
have_seeded_siphash = 1;
return 0;
}
/** Initialize the crypto library. Return 0 on success, -1 on failure.
*/
int
crypto_early_init(void)
{
if (!crypto_early_initialized_) {
crypto_early_initialized_ = 1;
#ifdef OPENSSL_1_1_API
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS |
OPENSSL_INIT_LOAD_CRYPTO_STRINGS |
OPENSSL_INIT_ADD_ALL_CIPHERS |
OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
#else
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
#endif
setup_openssl_threading();
unsigned long version_num = OpenSSL_version_num();
const char *version_str = OpenSSL_version(OPENSSL_VERSION);
if (version_num == OPENSSL_VERSION_NUMBER &&
!strcmp(version_str, OPENSSL_VERSION_TEXT)) {
log_info(LD_CRYPTO, "OpenSSL version matches version from headers "
"(%lx: %s).", version_num, version_str);
} else {
log_warn(LD_CRYPTO, "OpenSSL version from headers does not match the "
"version we're running with. If you get weird crashes, that "
"might be why. (Compiled with %lx: %s; running with %lx: %s).",
(unsigned long)OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT,
version_num, version_str);
}
crypto_force_rand_ssleay();
if (crypto_seed_rng() < 0)
return -1;
if (crypto_init_siphash_key() < 0)
return -1;
curve25519_init();
ed25519_init();
}
return 0;
}
/** Initialize the crypto library. Return 0 on success, -1 on failure.
*/
int
crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
{
if (!crypto_global_initialized_) {
if (crypto_early_init() < 0)
return -1;
crypto_global_initialized_ = 1;
if (useAccel > 0) {
#ifdef DISABLE_ENGINES
(void)accelName;
(void)accelDir;
log_warn(LD_CRYPTO, "No OpenSSL hardware acceleration support enabled.");
#else
ENGINE *e = NULL;
log_info(LD_CRYPTO, "Initializing OpenSSL engine support.");
ENGINE_load_builtin_engines();
ENGINE_register_all_complete();
if (accelName) {
if (accelDir) {
log_info(LD_CRYPTO, "Trying to load dynamic OpenSSL engine \"%s\""
" via path \"%s\".", accelName, accelDir);
e = try_load_engine(accelName, accelDir);
} else {
log_info(LD_CRYPTO, "Initializing dynamic OpenSSL engine \"%s\""
" acceleration support.", accelName);
e = ENGINE_by_id(accelName);
}
if (!e) {
log_warn(LD_CRYPTO, "Unable to load dynamic OpenSSL engine \"%s\".",
accelName);
} else {
log_info(LD_CRYPTO, "Loaded dynamic OpenSSL engine \"%s\".",
accelName);
}
}
if (e) {
log_info(LD_CRYPTO, "Loaded OpenSSL hardware acceleration engine,"
" setting default ciphers.");
ENGINE_set_default(e, ENGINE_METHOD_ALL);
}
/* Log, if available, the intersection of the set of algorithms
used by Tor and the set of algorithms available in the engine */
log_engine("RSA", ENGINE_get_default_RSA());
log_engine("DH", ENGINE_get_default_DH());
#ifdef OPENSSL_1_1_API
log_engine("EC", ENGINE_get_default_EC());
#else
log_engine("ECDH", ENGINE_get_default_ECDH());
log_engine("ECDSA", ENGINE_get_default_ECDSA());
#endif /* defined(OPENSSL_1_1_API) */
log_engine("RAND", ENGINE_get_default_RAND());
log_engine("RAND (which we will not use)", ENGINE_get_default_RAND());
log_engine("SHA1", ENGINE_get_digest_engine(NID_sha1));
log_engine("3DES-CBC", ENGINE_get_cipher_engine(NID_des_ede3_cbc));
log_engine("AES-128-ECB", ENGINE_get_cipher_engine(NID_aes_128_ecb));
log_engine("AES-128-CBC", ENGINE_get_cipher_engine(NID_aes_128_cbc));
#ifdef NID_aes_128_ctr
log_engine("AES-128-CTR", ENGINE_get_cipher_engine(NID_aes_128_ctr));
#endif
#ifdef NID_aes_128_gcm
log_engine("AES-128-GCM", ENGINE_get_cipher_engine(NID_aes_128_gcm));
#endif
log_engine("AES-256-CBC", ENGINE_get_cipher_engine(NID_aes_256_cbc));
#ifdef NID_aes_256_gcm
log_engine("AES-256-GCM", ENGINE_get_cipher_engine(NID_aes_256_gcm));
#endif
#endif /* defined(DISABLE_ENGINES) */
} else {
log_info(LD_CRYPTO, "NOT using OpenSSL engine support.");
}
if (crypto_force_rand_ssleay()) {
if (crypto_seed_rng() < 0)
return -1;
}
evaluate_evp_for_aes(-1);
evaluate_ctr_for_aes();
}
return 0;
}
/** Free crypto resources held by this thread. */
void
crypto_thread_cleanup(void)
{
#ifndef NEW_THREAD_API
ERR_remove_thread_state(NULL);
#endif
}
/** Allocate and return a new symmetric cipher using the provided key and iv.
* The key is <b>bits</b> bits long; the IV is CIPHER_IV_LEN bytes. Both
* must be provided. Key length must be 128, 192, or 256 */
crypto_cipher_t *
crypto_cipher_new_with_iv_and_bits(const uint8_t *key,
const uint8_t *iv,
int bits)
{
tor_assert(key);
tor_assert(iv);
return aes_new_cipher((const uint8_t*)key, (const uint8_t*)iv, bits);
}
/** Allocate and return a new symmetric cipher using the provided key and iv.
* The key is CIPHER_KEY_LEN bytes; the IV is CIPHER_IV_LEN bytes. Both
* must be provided.
*/
crypto_cipher_t *
crypto_cipher_new_with_iv(const char *key, const char *iv)
{
return crypto_cipher_new_with_iv_and_bits((uint8_t*)key, (uint8_t*)iv,
128);
}
/** Return a new crypto_cipher_t with the provided <b>key</b> and an IV of all
* zero bytes and key length <b>bits</b>. Key length must be 128, 192, or
* 256. */
crypto_cipher_t *
crypto_cipher_new_with_bits(const char *key, int bits)
{
char zeroiv[CIPHER_IV_LEN];
memset(zeroiv, 0, sizeof(zeroiv));
return crypto_cipher_new_with_iv_and_bits((uint8_t*)key, (uint8_t*)zeroiv,
bits);
}
/** Return a new crypto_cipher_t with the provided <b>key</b> (of
* CIPHER_KEY_LEN bytes) and an IV of all zero bytes. */
crypto_cipher_t *
crypto_cipher_new(const char *key)
{
return crypto_cipher_new_with_bits(key, 128);
}
2004-05-10 05:53:24 +02:00
/** Free a symmetric cipher.
*/
void
crypto_cipher_free_(crypto_cipher_t *env)
{
if (!env)
return;
aes_cipher_free(env);
}
/** Copy <b>in</b> to the <b>outlen</b>-byte buffer <b>out</b>, adding spaces
* every four characters. */
void
crypto_add_spaces_to_fp(char *out, size_t outlen, const char *in)
{
int n = 0;
char *end = out+outlen;
tor_assert(outlen < SIZE_T_CEILING);
while (*in && out<end) {
*out++ = *in++;
if (++n == 4 && *in && out<end) {
n = 0;
*out++ = ' ';
}
}
tor_assert(out<end);
*out = '\0';
}
/* symmetric crypto */
2004-05-10 05:53:24 +02:00
/** Encrypt <b>fromlen</b> bytes from <b>from</b> using the cipher
* <b>env</b>; on success, store the result to <b>to</b> and return 0.
* Does not check for failure.
*/
int
crypto_cipher_encrypt(crypto_cipher_t *env, char *to,
const char *from, size_t fromlen)
{
tor_assert(env);
tor_assert(env);
tor_assert(from);
tor_assert(fromlen);
tor_assert(to);
tor_assert(fromlen < SIZE_T_CEILING);
memcpy(to, from, fromlen);
aes_crypt_inplace(env, to, fromlen);
return 0;
}
2004-05-10 05:53:24 +02:00
/** Decrypt <b>fromlen</b> bytes from <b>from</b> using the cipher
* <b>env</b>; on success, store the result to <b>to</b> and return 0.
* Does not check for failure.
*/
int
crypto_cipher_decrypt(crypto_cipher_t *env, char *to,
const char *from, size_t fromlen)
{
tor_assert(env);
tor_assert(from);
tor_assert(to);
tor_assert(fromlen < SIZE_T_CEILING);
memcpy(to, from, fromlen);
aes_crypt_inplace(env, to, fromlen);
return 0;
}
/** Encrypt <b>len</b> bytes on <b>from</b> using the cipher in <b>env</b>;
* on success. Does not check for failure.
*/
void
crypto_cipher_crypt_inplace(crypto_cipher_t *env, char *buf, size_t len)
{
tor_assert(len < SIZE_T_CEILING);
aes_crypt_inplace(env, buf, len);
}
/** Encrypt <b>fromlen</b> bytes (at least 1) from <b>from</b> with the key in
* <b>key</b> to the buffer in <b>to</b> of length
* <b>tolen</b>. <b>tolen</b> must be at least <b>fromlen</b> plus
* CIPHER_IV_LEN bytes for the initialization vector. On success, return the
* number of bytes written, on failure, return -1.
*/
int
crypto_cipher_encrypt_with_iv(const char *key,
char *to, size_t tolen,
const char *from, size_t fromlen)
{
crypto_cipher_t *cipher;
tor_assert(from);
tor_assert(to);
tor_assert(fromlen < INT_MAX);
if (fromlen < 1)
return -1;
if (tolen < fromlen + CIPHER_IV_LEN)
return -1;
char iv[CIPHER_IV_LEN];
crypto_rand(iv, sizeof(iv));
cipher = crypto_cipher_new_with_iv(key, iv);
memcpy(to, iv, CIPHER_IV_LEN);
crypto_cipher_encrypt(cipher, to+CIPHER_IV_LEN, from, fromlen);
crypto_cipher_free(cipher);
memwipe(iv, 0, sizeof(iv));
return (int)(fromlen + CIPHER_IV_LEN);
}
/** Decrypt <b>fromlen</b> bytes (at least 1+CIPHER_IV_LEN) from <b>from</b>
* with the key in <b>key</b> to the buffer in <b>to</b> of length
* <b>tolen</b>. <b>tolen</b> must be at least <b>fromlen</b> minus
* CIPHER_IV_LEN bytes for the initialization vector. On success, return the
* number of bytes written, on failure, return -1.
*/
int
crypto_cipher_decrypt_with_iv(const char *key,
char *to, size_t tolen,
const char *from, size_t fromlen)
{
crypto_cipher_t *cipher;
tor_assert(key);
tor_assert(from);
tor_assert(to);
tor_assert(fromlen < INT_MAX);
if (fromlen <= CIPHER_IV_LEN)
return -1;
if (tolen < fromlen - CIPHER_IV_LEN)
return -1;
cipher = crypto_cipher_new_with_iv(key, from);
crypto_cipher_encrypt(cipher, to, from+CIPHER_IV_LEN, fromlen-CIPHER_IV_LEN);
crypto_cipher_free(cipher);
return (int)(fromlen - CIPHER_IV_LEN);
}
/** @{ */
/** Uninitialize the crypto library. Return 0 on success. Does not detect
* failure.
*/
int
crypto_global_cleanup(void)
{
#ifndef OPENSSL_1_1_API
EVP_cleanup();
#endif
#ifndef NEW_THREAD_API
ERR_remove_thread_state(NULL);
#endif
#ifndef OPENSSL_1_1_API
ERR_free_strings();
#endif
crypto_dh_free_all();
#ifndef DISABLE_ENGINES
#ifndef OPENSSL_1_1_API
ENGINE_cleanup();
#endif
#endif
CONF_modules_unload(1);
#ifndef OPENSSL_1_1_API
CRYPTO_cleanup_all_ex_data();
#endif
crypto_openssl_free_all();
crypto_early_initialized_ = 0;
crypto_global_initialized_ = 0;
have_seeded_siphash = 0;
siphash_unset_global_key();
return 0;
}
/** @} */