2007-12-12 22:09:01 +01:00
|
|
|
/* Copyright (c) 2001, Matej Pfajfar.
|
2006-02-09 06:46:49 +01:00
|
|
|
* Copyright (c) 2001-2004, Roger Dingledine.
|
2007-12-12 22:09:01 +01:00
|
|
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
2018-06-20 14:13:28 +02:00
|
|
|
* Copyright (c) 2007-2018, The Tor Project, Inc. */
|
2002-07-24 16:02:39 +02:00
|
|
|
/* See LICENSE for licensing information */
|
|
|
|
|
2004-05-10 05:53:24 +02:00
|
|
|
/**
|
|
|
|
* \file crypto.c
|
2005-06-11 07:31:17 +02:00
|
|
|
* \brief Wrapper functions to present a consistent interface to
|
2016-02-28 17:57:47 +01:00
|
|
|
* public-key and symmetric cryptography operations from OpenSSL and
|
|
|
|
* other places.
|
2004-05-10 05:53:24 +02:00
|
|
|
**/
|
|
|
|
|
2004-04-03 06:05:12 +02:00
|
|
|
#include "orconfig.h"
|
2004-03-11 07:19:08 +01:00
|
|
|
|
2012-01-31 16:59:42 +01:00
|
|
|
#ifdef _WIN32
|
2015-06-29 19:47:44 +02:00
|
|
|
#include <winsock2.h>
|
2004-04-28 22:13:21 +02:00
|
|
|
#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
|
2008-06-28 06:16:17 +02:00
|
|
|
* use either definition. */
|
|
|
|
#undef OCSP_RESPONSE
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(_WIN32) */
|
2004-04-28 22:13:21 +02:00
|
|
|
|
2015-05-21 17:54:13 +02:00
|
|
|
#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"
|
2015-05-21 17:54:13 +02:00
|
|
|
|
2016-06-15 02:21:02 +02:00
|
|
|
DISABLE_GCC_WARNING(redundant-decls)
|
2016-06-15 02:14:53 +02:00
|
|
|
|
2002-08-22 09:30:03 +02:00
|
|
|
#include <openssl/err.h>
|
|
|
|
#include <openssl/evp.h>
|
2009-05-24 01:42:44 +02:00
|
|
|
#include <openssl/engine.h>
|
2003-05-01 02:53:46 +02:00
|
|
|
#include <openssl/bn.h>
|
|
|
|
#include <openssl/dh.h>
|
2005-10-25 21:01:48 +02:00
|
|
|
#include <openssl/conf.h>
|
2007-11-01 04:56:17 +01:00
|
|
|
#include <openssl/hmac.h>
|
2018-04-18 18:31:24 +02:00
|
|
|
#include <openssl/ssl.h>
|
2002-07-24 16:02:39 +02:00
|
|
|
|
2016-06-15 02:21:02 +02:00
|
|
|
ENABLE_GCC_WARNING(redundant-decls)
|
|
|
|
|
2016-06-15 02:14:53 +02:00
|
|
|
#if __GNUC__ && GCC_VERSION >= 402
|
|
|
|
#if GCC_VERSION >= 406
|
|
|
|
#pragma GCC diagnostic pop
|
|
|
|
#else
|
|
|
|
#pragma GCC diagnostic warning "-Wredundant-decls"
|
|
|
|
#endif
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* __GNUC__ && GCC_VERSION >= 402 */
|
2016-06-15 02:14:53 +02:00
|
|
|
|
2004-04-03 06:05:12 +02:00
|
|
|
#ifdef HAVE_CTYPE_H
|
|
|
|
#include <ctype.h>
|
|
|
|
#endif
|
2004-04-26 20:09:50 +02:00
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
2004-04-03 06:05:12 +02:00
|
|
|
|
2018-06-20 15:35:05 +02:00
|
|
|
#include "common/torlog.h"
|
|
|
|
#include "common/torint.h"
|
|
|
|
#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"
|
2002-08-22 09:30:03 +02:00
|
|
|
|
2015-12-18 23:15:01 +01:00
|
|
|
#include "keccak-tiny/keccak-tiny.h"
|
|
|
|
|
2014-02-12 17:56:29 +01:00
|
|
|
/** 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? */
|
2012-10-12 18:22:13 +02:00
|
|
|
static int crypto_global_initialized_ = 0;
|
2003-09-15 21:38:52 +02:00
|
|
|
|
2009-09-29 06:46:53 +02:00
|
|
|
#ifndef DISABLE_ENGINES
|
2006-09-29 20:13:37 +02:00
|
|
|
/** Log any OpenSSL engines we're using at NOTICE. */
|
2005-06-20 20:56:35 +02:00
|
|
|
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);
|
2013-12-18 17:49:44 +01:00
|
|
|
log_notice(LD_CRYPTO, "Default OpenSSL engine for %s is %s [%s]",
|
|
|
|
fn, name?name:"?", id?id:"?");
|
2005-06-20 20:56:35 +02:00
|
|
|
} else {
|
2013-02-01 21:43:37 +01:00
|
|
|
log_info(LD_CRYPTO, "Using default implementation for %s", fn);
|
2005-06-20 20:56:35 +02:00
|
|
|
}
|
|
|
|
}
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* !defined(DISABLE_ENGINES) */
|
2005-06-20 20:56:35 +02:00
|
|
|
|
2009-09-29 06:46:53 +02:00
|
|
|
#ifndef DISABLE_ENGINES
|
2009-05-24 01:42:44 +02:00
|
|
|
/** 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;
|
|
|
|
}
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* !defined(DISABLE_ENGINES) */
|
2009-05-24 01:42:44 +02:00
|
|
|
|
2018-01-11 18:49:28 +01:00
|
|
|
static int have_seeded_siphash = 0;
|
|
|
|
|
2014-02-12 17:46:58 +01:00
|
|
|
/** 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;
|
|
|
|
|
2015-11-25 16:42:00 +01:00
|
|
|
crypto_rand((char*) &key, sizeof(key));
|
2014-02-12 17:46:58 +01:00
|
|
|
siphash_set_global_key(&key);
|
|
|
|
have_seeded_siphash = 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Initialize the crypto library. Return 0 on success, -1 on failure.
|
2004-05-01 22:46:28 +02:00
|
|
|
*/
|
2005-06-20 20:56:35 +02:00
|
|
|
int
|
2014-02-12 17:56:29 +01:00
|
|
|
crypto_early_init(void)
|
2002-07-24 16:02:39 +02:00
|
|
|
{
|
2014-02-12 17:56:29 +01:00
|
|
|
if (!crypto_early_initialized_) {
|
2014-03-23 05:38:17 +01:00
|
|
|
|
|
|
|
crypto_early_initialized_ = 1;
|
|
|
|
|
2018-05-03 19:33:14 +02:00
|
|
|
#ifdef OPENSSL_1_1_API
|
2018-04-18 18:31:24 +02:00
|
|
|
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
|
2005-06-20 20:56:35 +02:00
|
|
|
ERR_load_crypto_strings();
|
|
|
|
OpenSSL_add_all_algorithms();
|
2018-04-18 18:31:24 +02:00
|
|
|
#endif
|
2014-02-12 17:56:29 +01:00
|
|
|
|
2005-06-20 20:56:35 +02:00
|
|
|
setup_openssl_threading();
|
2012-09-04 18:41:37 +02:00
|
|
|
|
2015-11-06 20:02:56 +01:00
|
|
|
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)) {
|
2012-09-04 18:41:37 +02:00
|
|
|
log_info(LD_CRYPTO, "OpenSSL version matches version from headers "
|
2015-11-06 20:02:56 +01:00
|
|
|
"(%lx: %s).", version_num, version_str);
|
2012-09-04 18:41:37 +02:00
|
|
|
} 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,
|
2015-11-06 20:02:56 +01:00
|
|
|
version_num, version_str);
|
2012-09-04 18:41:37 +02:00
|
|
|
}
|
|
|
|
|
2014-02-12 17:56:29 +01:00
|
|
|
crypto_force_rand_ssleay();
|
|
|
|
|
2015-05-19 22:17:03 +02:00
|
|
|
if (crypto_seed_rng() < 0)
|
2014-02-12 17:56:29 +01:00
|
|
|
return -1;
|
2014-02-12 17:46:58 +01:00
|
|
|
if (crypto_init_siphash_key() < 0)
|
|
|
|
return -1;
|
2015-07-06 11:57:23 +02:00
|
|
|
|
|
|
|
curve25519_init();
|
2015-07-06 12:11:10 +02:00
|
|
|
ed25519_init();
|
2014-02-12 17:56:29 +01:00
|
|
|
}
|
|
|
|
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_) {
|
2015-11-25 16:36:34 +01:00
|
|
|
if (crypto_early_init() < 0)
|
|
|
|
return -1;
|
2014-02-12 17:56:29 +01:00
|
|
|
|
|
|
|
crypto_global_initialized_ = 1;
|
|
|
|
|
2006-05-24 02:37:38 +02:00
|
|
|
if (useAccel > 0) {
|
2009-09-29 06:46:53 +02:00
|
|
|
#ifdef DISABLE_ENGINES
|
|
|
|
(void)accelName;
|
|
|
|
(void)accelDir;
|
|
|
|
log_warn(LD_CRYPTO, "No OpenSSL hardware acceleration support enabled.");
|
|
|
|
#else
|
2009-05-24 01:42:44 +02:00
|
|
|
ENGINE *e = NULL;
|
2009-09-29 06:46:53 +02:00
|
|
|
|
2006-02-13 09:01:59 +01:00
|
|
|
log_info(LD_CRYPTO, "Initializing OpenSSL engine support.");
|
2005-06-20 20:56:35 +02:00
|
|
|
ENGINE_load_builtin_engines();
|
2009-05-24 01:42:44 +02:00
|
|
|
ENGINE_register_all_complete();
|
2009-09-29 06:46:53 +02:00
|
|
|
|
2009-05-24 01:42:44 +02:00
|
|
|
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);
|
|
|
|
}
|
2013-11-18 17:12:24 +01:00
|
|
|
/* Log, if available, the intersection of the set of algorithms
|
|
|
|
used by Tor and the set of algorithms available in the engine */
|
2005-06-20 20:56:35 +02:00
|
|
|
log_engine("RSA", ENGINE_get_default_RSA());
|
|
|
|
log_engine("DH", ENGINE_get_default_DH());
|
2016-02-03 17:13:12 +01:00
|
|
|
#ifdef OPENSSL_1_1_API
|
|
|
|
log_engine("EC", ENGINE_get_default_EC());
|
|
|
|
#else
|
2013-11-18 17:12:24 +01:00
|
|
|
log_engine("ECDH", ENGINE_get_default_ECDH());
|
|
|
|
log_engine("ECDSA", ENGINE_get_default_ECDSA());
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(OPENSSL_1_1_API) */
|
2005-06-20 20:56:35 +02:00
|
|
|
log_engine("RAND", ENGINE_get_default_RAND());
|
2013-12-18 17:49:44 +01:00
|
|
|
log_engine("RAND (which we will not use)", ENGINE_get_default_RAND());
|
2005-06-20 20:56:35 +02:00
|
|
|
log_engine("SHA1", ENGINE_get_digest_engine(NID_sha1));
|
2013-11-18 17:12:24 +01:00
|
|
|
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));
|
2013-11-18 17:23:54 +01:00
|
|
|
#ifdef NID_aes_128_ctr
|
2013-11-18 17:12:24 +01:00
|
|
|
log_engine("AES-128-CTR", ENGINE_get_cipher_engine(NID_aes_128_ctr));
|
2013-11-18 17:23:54 +01:00
|
|
|
#endif
|
|
|
|
#ifdef NID_aes_128_gcm
|
2013-11-18 17:12:24 +01:00
|
|
|
log_engine("AES-128-GCM", ENGINE_get_cipher_engine(NID_aes_128_gcm));
|
2013-11-18 17:23:54 +01:00
|
|
|
#endif
|
2013-11-18 17:12:24 +01:00
|
|
|
log_engine("AES-256-CBC", ENGINE_get_cipher_engine(NID_aes_256_cbc));
|
2013-11-18 17:23:54 +01:00
|
|
|
#ifdef NID_aes_256_gcm
|
2013-11-18 17:12:24 +01:00
|
|
|
log_engine("AES-256-GCM", ENGINE_get_cipher_engine(NID_aes_256_gcm));
|
2013-11-18 17:23:54 +01:00
|
|
|
#endif
|
2013-11-18 17:12:24 +01:00
|
|
|
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(DISABLE_ENGINES) */
|
2009-05-24 01:42:44 +02:00
|
|
|
} else {
|
|
|
|
log_info(LD_CRYPTO, "NOT using OpenSSL engine support.");
|
2005-06-20 20:56:35 +02:00
|
|
|
}
|
2011-11-21 03:20:31 +01:00
|
|
|
|
2014-02-12 17:56:29 +01:00
|
|
|
if (crypto_force_rand_ssleay()) {
|
2015-05-19 22:17:03 +02:00
|
|
|
if (crypto_seed_rng() < 0)
|
2014-02-12 17:56:29 +01:00
|
|
|
return -1;
|
2013-12-18 17:49:44 +01:00
|
|
|
}
|
|
|
|
|
2011-11-21 03:20:31 +01:00
|
|
|
evaluate_evp_for_aes(-1);
|
2012-01-09 23:40:11 +01:00
|
|
|
evaluate_ctr_for_aes();
|
2003-09-15 21:38:52 +02:00
|
|
|
}
|
2002-07-24 16:02:39 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-10-25 21:01:48 +02:00
|
|
|
/** Free crypto resources held by this thread. */
|
|
|
|
void
|
|
|
|
crypto_thread_cleanup(void)
|
|
|
|
{
|
2016-06-14 06:40:36 +02:00
|
|
|
#ifndef NEW_THREAD_API
|
2015-11-10 16:13:04 +01:00
|
|
|
ERR_remove_thread_state(NULL);
|
2016-04-04 05:51:47 +02:00
|
|
|
#endif
|
2005-10-25 21:01:48 +02:00
|
|
|
}
|
|
|
|
|
2012-03-20 20:35:43 +01:00
|
|
|
/** Allocate and return a new symmetric cipher using the provided key and iv.
|
2016-09-16 17:21:33 +02:00
|
|
|
* 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 */
|
2012-01-18 21:53:30 +01:00
|
|
|
crypto_cipher_t *
|
2016-09-16 17:21:33 +02:00
|
|
|
crypto_cipher_new_with_iv_and_bits(const uint8_t *key,
|
|
|
|
const uint8_t *iv,
|
|
|
|
int bits)
|
2002-10-02 22:39:51 +02:00
|
|
|
{
|
2016-09-16 16:12:30 +02:00
|
|
|
tor_assert(key);
|
|
|
|
tor_assert(iv);
|
2002-10-02 22:39:51 +02:00
|
|
|
|
2016-09-16 17:21:33 +02:00
|
|
|
return aes_new_cipher((const uint8_t*)key, (const uint8_t*)iv, bits);
|
|
|
|
}
|
2002-10-02 22:39:51 +02:00
|
|
|
|
2016-09-16 17:21:33 +02:00
|
|
|
/** 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);
|
2002-10-02 22:39:51 +02:00
|
|
|
}
|
|
|
|
|
2012-06-05 01:51:00 +02:00
|
|
|
/** Return a new crypto_cipher_t with the provided <b>key</b> and an IV of all
|
2016-09-16 17:21:33 +02:00
|
|
|
* zero bytes and key length <b>bits</b>. Key length must be 128, 192, or
|
|
|
|
* 256. */
|
2012-01-18 21:53:30 +01:00
|
|
|
crypto_cipher_t *
|
2016-09-16 17:21:33 +02:00
|
|
|
crypto_cipher_new_with_bits(const char *key, int bits)
|
2002-07-24 16:02:39 +02:00
|
|
|
{
|
2012-03-20 20:35:43 +01:00
|
|
|
char zeroiv[CIPHER_IV_LEN];
|
|
|
|
memset(zeroiv, 0, sizeof(zeroiv));
|
2016-09-16 17:21:33 +02:00
|
|
|
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);
|
2002-07-24 16:02:39 +02:00
|
|
|
}
|
|
|
|
|
2004-05-10 05:53:24 +02:00
|
|
|
/** Free a symmetric cipher.
|
2004-05-01 23:41:23 +02:00
|
|
|
*/
|
2005-09-30 03:09:52 +02:00
|
|
|
void
|
2017-11-17 17:55:52 +01:00
|
|
|
crypto_cipher_free_(crypto_cipher_t *env)
|
2002-07-24 16:02:39 +02:00
|
|
|
{
|
2009-09-28 16:37:01 +02:00
|
|
|
if (!env)
|
|
|
|
return;
|
2003-03-19 21:41:15 +01:00
|
|
|
|
2016-09-16 16:18:02 +02:00
|
|
|
aes_cipher_free(env);
|
2002-07-24 16:02:39 +02:00
|
|
|
}
|
|
|
|
|
2008-02-16 00:39:14 +01:00
|
|
|
/** Copy <b>in</b> to the <b>outlen</b>-byte buffer <b>out</b>, adding spaces
|
2015-11-23 08:59:11 +01:00
|
|
|
* every four characters. */
|
2013-06-06 23:58:28 +02:00
|
|
|
void
|
|
|
|
crypto_add_spaces_to_fp(char *out, size_t outlen, const char *in)
|
2008-02-16 00:39:14 +01:00
|
|
|
{
|
|
|
|
int n = 0;
|
|
|
|
char *end = out+outlen;
|
2010-12-14 00:40:21 +01:00
|
|
|
tor_assert(outlen < SIZE_T_CEILING);
|
|
|
|
|
2008-02-16 00:39:14 +01:00
|
|
|
while (*in && out<end) {
|
|
|
|
*out++ = *in++;
|
|
|
|
if (++n == 4 && *in && out<end) {
|
|
|
|
n = 0;
|
|
|
|
*out++ = ' ';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tor_assert(out<end);
|
|
|
|
*out = '\0';
|
|
|
|
}
|
|
|
|
|
2002-07-24 16:02:39 +02:00
|
|
|
/* symmetric crypto */
|
2004-05-01 23:41:23 +02:00
|
|
|
|
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.
|
2015-11-23 10:31:57 +01:00
|
|
|
* Does not check for failure.
|
2004-05-01 23:41:23 +02:00
|
|
|
*/
|
2004-11-02 03:28:51 +01:00
|
|
|
int
|
2012-01-18 21:53:30 +01:00
|
|
|
crypto_cipher_encrypt(crypto_cipher_t *env, char *to,
|
2005-05-07 07:55:06 +02:00
|
|
|
const char *from, size_t fromlen)
|
2002-07-24 16:02:39 +02:00
|
|
|
{
|
2004-10-17 00:28:11 +02:00
|
|
|
tor_assert(env);
|
2016-09-16 16:18:02 +02:00
|
|
|
tor_assert(env);
|
2004-10-17 00:28:11 +02:00
|
|
|
tor_assert(from);
|
|
|
|
tor_assert(fromlen);
|
|
|
|
tor_assert(to);
|
2010-12-14 00:40:21 +01:00
|
|
|
tor_assert(fromlen < SIZE_T_CEILING);
|
2003-12-16 06:29:04 +01:00
|
|
|
|
2016-02-06 18:05:32 +01:00
|
|
|
memcpy(to, from, fromlen);
|
2016-09-16 16:18:02 +02:00
|
|
|
aes_crypt_inplace(env, to, fromlen);
|
2004-04-03 04:40:30 +02:00
|
|
|
return 0;
|
2002-07-24 16:02:39 +02:00
|
|
|
}
|
|
|
|
|
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.
|
2015-11-23 10:31:57 +01:00
|
|
|
* Does not check for failure.
|
2004-05-01 23:41:23 +02:00
|
|
|
*/
|
2004-11-02 03:28:51 +01:00
|
|
|
int
|
2012-01-18 21:53:30 +01:00
|
|
|
crypto_cipher_decrypt(crypto_cipher_t *env, char *to,
|
2005-05-07 07:55:06 +02:00
|
|
|
const char *from, size_t fromlen)
|
2002-07-24 16:02:39 +02:00
|
|
|
{
|
2004-10-17 00:28:11 +02:00
|
|
|
tor_assert(env);
|
|
|
|
tor_assert(from);
|
|
|
|
tor_assert(to);
|
2010-12-14 00:40:21 +01:00
|
|
|
tor_assert(fromlen < SIZE_T_CEILING);
|
2003-06-30 21:18:32 +02:00
|
|
|
|
2016-02-06 18:05:32 +01:00
|
|
|
memcpy(to, from, fromlen);
|
2016-09-16 16:18:02 +02:00
|
|
|
aes_crypt_inplace(env, to, fromlen);
|
2004-04-03 04:40:30 +02:00
|
|
|
return 0;
|
2003-06-30 21:18:32 +02:00
|
|
|
}
|
|
|
|
|
2008-02-07 17:10:33 +01:00
|
|
|
/** Encrypt <b>len</b> bytes on <b>from</b> using the cipher in <b>env</b>;
|
2016-02-06 18:14:39 +01:00
|
|
|
* on success. Does not check for failure.
|
2008-02-07 17:10:33 +01:00
|
|
|
*/
|
2016-02-06 18:14:39 +01:00
|
|
|
void
|
2012-01-18 21:53:30 +01:00
|
|
|
crypto_cipher_crypt_inplace(crypto_cipher_t *env, char *buf, size_t len)
|
2008-02-07 17:10:33 +01:00
|
|
|
{
|
2010-12-14 00:40:21 +01:00
|
|
|
tor_assert(len < SIZE_T_CEILING);
|
2016-09-16 16:18:02 +02:00
|
|
|
aes_crypt_inplace(env, buf, len);
|
2008-02-07 17:10:33 +01:00
|
|
|
}
|
|
|
|
|
2007-09-19 17:53:41 +02:00
|
|
|
/** Encrypt <b>fromlen</b> bytes (at least 1) from <b>from</b> with the key in
|
2012-03-20 20:35:43 +01:00
|
|
|
* <b>key</b> to the buffer in <b>to</b> of length
|
2007-09-19 17:53:41 +02:00
|
|
|
* <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
|
2012-03-20 20:35:43 +01:00
|
|
|
crypto_cipher_encrypt_with_iv(const char *key,
|
2007-09-19 17:53:41 +02:00
|
|
|
char *to, size_t tolen,
|
|
|
|
const char *from, size_t fromlen)
|
|
|
|
{
|
2012-03-20 20:35:43 +01:00
|
|
|
crypto_cipher_t *cipher;
|
2007-09-19 17:53:41 +02:00
|
|
|
tor_assert(from);
|
|
|
|
tor_assert(to);
|
2008-02-21 22:57:47 +01:00
|
|
|
tor_assert(fromlen < INT_MAX);
|
2007-09-19 17:53:41 +02:00
|
|
|
|
2007-09-20 22:08:47 +02:00
|
|
|
if (fromlen < 1)
|
|
|
|
return -1;
|
2007-09-19 17:53:41 +02:00
|
|
|
if (tolen < fromlen + CIPHER_IV_LEN)
|
|
|
|
return -1;
|
|
|
|
|
2016-09-16 16:12:30 +02:00
|
|
|
char iv[CIPHER_IV_LEN];
|
|
|
|
crypto_rand(iv, sizeof(iv));
|
|
|
|
cipher = crypto_cipher_new_with_iv(key, iv);
|
2012-03-20 20:35:43 +01:00
|
|
|
|
2016-09-16 16:12:30 +02:00
|
|
|
memcpy(to, iv, CIPHER_IV_LEN);
|
2007-09-19 17:53:41 +02:00
|
|
|
crypto_cipher_encrypt(cipher, to+CIPHER_IV_LEN, from, fromlen);
|
2012-03-20 20:35:43 +01:00
|
|
|
crypto_cipher_free(cipher);
|
2016-09-16 16:12:30 +02:00
|
|
|
memwipe(iv, 0, sizeof(iv));
|
2008-02-21 22:57:47 +01:00
|
|
|
return (int)(fromlen + CIPHER_IV_LEN);
|
2007-09-19 17:53:41 +02:00
|
|
|
}
|
|
|
|
|
2007-09-20 22:08:47 +02:00
|
|
|
/** Decrypt <b>fromlen</b> bytes (at least 1+CIPHER_IV_LEN) from <b>from</b>
|
2012-03-20 20:35:43 +01:00
|
|
|
* with the key in <b>key</b> to the buffer in <b>to</b> of length
|
2007-09-19 17:53:41 +02:00
|
|
|
* <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
|
2012-03-20 20:35:43 +01:00
|
|
|
crypto_cipher_decrypt_with_iv(const char *key,
|
2007-09-19 17:53:41 +02:00
|
|
|
char *to, size_t tolen,
|
|
|
|
const char *from, size_t fromlen)
|
|
|
|
{
|
2012-03-20 20:35:43 +01:00
|
|
|
crypto_cipher_t *cipher;
|
|
|
|
tor_assert(key);
|
2007-09-19 17:53:41 +02:00
|
|
|
tor_assert(from);
|
|
|
|
tor_assert(to);
|
2008-02-21 22:57:47 +01:00
|
|
|
tor_assert(fromlen < INT_MAX);
|
2007-09-19 17:53:41 +02:00
|
|
|
|
2007-09-20 22:08:47 +02:00
|
|
|
if (fromlen <= CIPHER_IV_LEN)
|
2007-09-19 17:53:41 +02:00
|
|
|
return -1;
|
|
|
|
if (tolen < fromlen - CIPHER_IV_LEN)
|
|
|
|
return -1;
|
|
|
|
|
2012-03-20 20:35:43 +01:00
|
|
|
cipher = crypto_cipher_new_with_iv(key, from);
|
|
|
|
|
2007-09-19 17:53:41 +02:00
|
|
|
crypto_cipher_encrypt(cipher, to, from+CIPHER_IV_LEN, fromlen-CIPHER_IV_LEN);
|
2012-03-20 20:35:43 +01:00
|
|
|
crypto_cipher_free(cipher);
|
2008-02-21 22:57:47 +01:00
|
|
|
return (int)(fromlen - CIPHER_IV_LEN);
|
2007-09-19 17:53:41 +02:00
|
|
|
}
|
|
|
|
|
2011-03-16 22:05:37 +01:00
|
|
|
/** @{ */
|
2015-11-23 10:31:57 +01:00
|
|
|
/** Uninitialize the crypto library. Return 0 on success. Does not detect
|
|
|
|
* failure.
|
2011-11-22 15:11:40 +01:00
|
|
|
*/
|
|
|
|
int
|
|
|
|
crypto_global_cleanup(void)
|
|
|
|
{
|
2018-05-03 19:33:14 +02:00
|
|
|
#ifndef OPENSSL_1_1_API
|
2011-11-22 15:11:40 +01:00
|
|
|
EVP_cleanup();
|
2018-04-18 18:31:24 +02:00
|
|
|
#endif
|
2016-06-14 06:40:36 +02:00
|
|
|
#ifndef NEW_THREAD_API
|
2015-11-10 16:13:04 +01:00
|
|
|
ERR_remove_thread_state(NULL);
|
2016-04-04 05:51:47 +02:00
|
|
|
#endif
|
2018-05-03 19:33:14 +02:00
|
|
|
#ifndef OPENSSL_1_1_API
|
2011-11-22 15:11:40 +01:00
|
|
|
ERR_free_strings();
|
2018-04-18 18:31:24 +02:00
|
|
|
#endif
|
2011-11-22 15:11:40 +01:00
|
|
|
|
2018-05-08 15:51:39 +02:00
|
|
|
crypto_dh_free_all();
|
2017-12-11 17:37:54 +01:00
|
|
|
|
2011-11-22 15:11:40 +01:00
|
|
|
#ifndef DISABLE_ENGINES
|
2018-05-03 19:33:14 +02:00
|
|
|
#ifndef OPENSSL_1_1_API
|
2011-11-22 15:11:40 +01:00
|
|
|
ENGINE_cleanup();
|
2018-04-18 18:31:24 +02:00
|
|
|
#endif
|
2011-11-22 15:11:40 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
CONF_modules_unload(1);
|
2018-05-03 19:33:14 +02:00
|
|
|
#ifndef OPENSSL_1_1_API
|
2011-11-22 15:11:40 +01:00
|
|
|
CRYPTO_cleanup_all_ex_data();
|
2018-04-18 18:31:24 +02:00
|
|
|
#endif
|
2014-06-20 16:20:10 +02:00
|
|
|
|
2018-01-19 18:07:49 +01:00
|
|
|
crypto_openssl_free_all();
|
2018-01-11 18:49:28 +01:00
|
|
|
|
|
|
|
crypto_early_initialized_ = 0;
|
|
|
|
crypto_global_initialized_ = 0;
|
|
|
|
have_seeded_siphash = 0;
|
|
|
|
siphash_unset_global_key();
|
|
|
|
|
2011-11-22 15:11:40 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-03-16 22:05:37 +01:00
|
|
|
/** @} */
|