aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2015-12-31 10:56:47 +0100
committerAndreas Schneider <asn@cryptomilk.org>2018-07-05 12:55:23 +0200
commit2b40ad29c02da4004dec3a0e51ea8cef4ebac01e (patch)
tree6f7754b58ac58ec92886a29c08ca7cff97d1d6fc
parent38c53db9533a3e0ac446ee0a83dac8768d282de9 (diff)
downloadlibssh-2b40ad29c02da4004dec3a0e51ea8cef4ebac01e.tar.gz
libssh-2b40ad29c02da4004dec3a0e51ea8cef4ebac01e.tar.xz
libssh-2b40ad29c02da4004dec3a0e51ea8cef4ebac01e.zip
crypto: Split init and finalize functions
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
-rw-r--r--include/libssh/dh.h4
-rw-r--r--include/libssh/libcrypto.h15
-rw-r--r--include/libssh/libgcrypt.h3
-rw-r--r--include/libssh/libmbedcrypto.h2
-rw-r--r--include/libssh/wrapper.h5
-rw-r--r--src/dh.c99
-rw-r--r--src/init.c46
-rw-r--r--src/libcrypto.c38
-rw-r--r--src/libgcrypt.c70
-rw-r--r--src/libmbedcrypto.c19
10 files changed, 188 insertions, 113 deletions
diff --git a/include/libssh/dh.h b/include/libssh/dh.h
index c54595ef..cfdcfeec 100644
--- a/include/libssh/dh.h
+++ b/include/libssh/dh.h
@@ -30,8 +30,8 @@ int ssh_dh_generate_f(ssh_session session);
int ssh_dh_generate_x(ssh_session session);
int ssh_dh_generate_y(ssh_session session);
-int ssh_crypto_init(void);
-void ssh_crypto_finalize(void);
+int ssh_dh_init(void);
+void ssh_dh_finalize(void);
ssh_string ssh_dh_get_e(ssh_session session);
ssh_string ssh_dh_get_f(ssh_session session);
diff --git a/include/libssh/libcrypto.h b/include/libssh/libcrypto.h
index e2d2baad..0207f047 100644
--- a/include/libssh/libcrypto.h
+++ b/include/libssh/libcrypto.h
@@ -83,21 +83,6 @@ typedef BN_CTX* bignum_CTX;
#define bignum_bn2bin(num,ptr) BN_bn2bin(num,ptr)
#define bignum_cmp(num1,num2) BN_cmp(num1,num2)
-SHA256CTX sha256_init(void);
-void sha256_update(SHA256CTX c, const void *data, unsigned long len);
-void sha256_final(unsigned char *md, SHA256CTX c);
-
-SHA384CTX sha384_init(void);
-void sha384_update(SHA384CTX c, const void *data, unsigned long len);
-void sha384_final(unsigned char *md, SHA384CTX c);
-
-SHA512CTX sha512_init(void);
-void sha512_update(SHA512CTX c, const void *data, unsigned long len);
-void sha512_final(unsigned char *md, SHA512CTX c);
-
-void libcrypto_init(void);
-struct ssh_cipher_struct *ssh_get_ciphertab(void);
-
#endif /* HAVE_LIBCRYPTO */
#endif /* LIBCRYPTO_H_ */
diff --git a/include/libssh/libgcrypt.h b/include/libssh/libgcrypt.h
index 307920d3..69e47683 100644
--- a/include/libssh/libgcrypt.h
+++ b/include/libssh/libgcrypt.h
@@ -88,7 +88,4 @@ ssh_string ssh_sexp_extract_mpi(const gcry_sexp_t sexp,
#endif /* HAVE_LIBGCRYPT */
-void libgcrypt_init(void);
-struct ssh_cipher_struct *ssh_get_ciphertab(void);
-
#endif /* LIBGCRYPT_H_ */
diff --git a/include/libssh/libmbedcrypto.h b/include/libssh/libmbedcrypto.h
index 9f8ee9a2..101cdee9 100644
--- a/include/libssh/libmbedcrypto.h
+++ b/include/libssh/libmbedcrypto.h
@@ -99,8 +99,6 @@ int ssh_mbedcry_is_bit_set(bignum num, size_t pos);
mbedtls_entropy_context ssh_mbedtls_entropy;
mbedtls_ctr_drbg_context ssh_mbedtls_ctr_drbg;
-void ssh_mbedtls_init(void);
-void ssh_mbedtls_cleanup(void);
int ssh_mbedtls_random(void *where, int len, int strong);
ssh_string make_ecpoint_string(const mbedtls_ecp_group *g, const
diff --git a/include/libssh/wrapper.h b/include/libssh/wrapper.h
index 003a61d8..62a974fd 100644
--- a/include/libssh/wrapper.h
+++ b/include/libssh/wrapper.h
@@ -53,6 +53,8 @@ struct ssh_hmac_struct {
enum ssh_hmac_e hmac_type;
};
+struct ssh_cipher_struct;
+
typedef struct ssh_mac_ctx_struct *ssh_mac_ctx;
MD5CTX md5_init(void);
void md5_update(MD5CTX c, const void *data, unsigned long len);
@@ -98,9 +100,12 @@ struct ssh_crypto_struct *crypto_new(void);
void crypto_free(struct ssh_crypto_struct *crypto);
void ssh_reseed(void);
+int ssh_crypto_init(void);
+void ssh_crypto_finalize(void);
void ssh_cipher_clear(struct ssh_cipher_struct *cipher);
struct ssh_hmac_struct *ssh_get_hmactab(void);
+struct ssh_cipher_struct *ssh_get_ciphertab(void);
const char *ssh_hmac_type_to_string(enum ssh_hmac_e hmac_type);
#endif /* WRAPPER_H_ */
diff --git a/src/dh.c b/src/dh.c
index 2be0252d..a58cfa9e 100644
--- a/src/dh.c
+++ b/src/dh.c
@@ -116,105 +116,92 @@ static unsigned long g_int = 2 ; /* G is defined as 2 by the ssh2 standards */
static bignum g;
static bignum p_group1;
static bignum p_group14;
-static int ssh_crypto_initialized;
+static int dh_crypto_initialized;
static bignum select_p(enum ssh_key_exchange_e type) {
return type == SSH_KEX_DH_GROUP14_SHA1 ? p_group14 : p_group1;
}
-/*
- * This inits the values g and p which are used for DH key agreement
- * FIXME: Make the function thread safe by adding a semaphore or mutex.
+/**
+ * @internal
+ * @brief Initialize global constants used in DH key agreement
+ * @return SSH_OK on success, SSH_ERROR otherwise.
*/
-int ssh_crypto_init(void) {
- if (ssh_crypto_initialized == 0) {
-#ifdef HAVE_LIBGCRYPT
- gcry_check_version(NULL);
- if (!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P,0)) {
- gcry_control(GCRYCTL_INIT_SECMEM, 4096);
- gcry_control(GCRYCTL_INITIALIZATION_FINISHED,0);
+int ssh_dh_init(void)
+{
+ if (dh_crypto_initialized) {
+ return SSH_OK;
}
-#elif HAVE_LIBMBEDCRYPTO
- ssh_mbedtls_init();
-#endif
g = bignum_new();
if (g == NULL) {
- return -1;
+ return SSH_ERROR;
}
bignum_set_word(g,g_int);
-#ifdef HAVE_LIBGCRYPT
+#if defined(HAVE_LIBGCRYPT)
bignum_bin2bn(p_group1_value, P_GROUP1_LEN, &p_group1);
if (p_group1 == NULL) {
- bignum_free(g);
- g = NULL;
- return -1;
+ bignum_free(g);
+ g = NULL;
+ return -1;
}
bignum_bin2bn(p_group14_value, P_GROUP14_LEN, &p_group14);
if (p_group14 == NULL) {
- bignum_free(g);
- bignum_free(p_group1);
- g = NULL;
- p_group1 = NULL;
- return -1;
+ bignum_free(g);
+ bignum_free(p_group1);
+ g = NULL;
+ p_group1 = NULL;
+ return -1;
}
- libgcrypt_init();
-
-#elif defined HAVE_LIBCRYPTO
+#elif defined(HAVE_LIBCRYPTO)
p_group1 = bignum_new();
if (p_group1 == NULL) {
- bignum_free(g);
- g = NULL;
- return -1;
+ bignum_free(g);
+ g = NULL;
+ return -1;
}
bignum_bin2bn(p_group1_value, P_GROUP1_LEN, p_group1);
p_group14 = bignum_new();
if (p_group14 == NULL) {
- bignum_free(g);
- bignum_free(p_group1);
- g = NULL;
- p_group1 = NULL;
- return -1;
+ bignum_free(g);
+ bignum_free(p_group1);
+ g = NULL;
+ p_group1 = NULL;
+ return SSH_ERROR;
}
bignum_bin2bn(p_group14_value, P_GROUP14_LEN, p_group14);
-
- OpenSSL_add_all_algorithms();
-
- libcrypto_init();
-#elif defined HAVE_LIBMBEDCRYPTO
+#elif defined(HAVE_LIBMBEDCRYPTO)
p_group1 = bignum_new();
bignum_bin2bn(p_group1_value, P_GROUP1_LEN, p_group1);
p_group14 = bignum_new();
bignum_bin2bn(p_group14_value, P_GROUP14_LEN, p_group14);
#endif
+ dh_crypto_initialized = 1;
- ssh_crypto_initialized = 1;
- }
-
- return 0;
+ return 0;
}
-void ssh_crypto_finalize(void) {
- if (ssh_crypto_initialized) {
+/**
+ * @internal
+ * @brief Finalize and free global constants used in DH key agreement
+ */
+void ssh_dh_finalize(void)
+{
+ if (!dh_crypto_initialized) {
+ return;
+ }
+
bignum_free(g);
g = NULL;
bignum_free(p_group1);
p_group1 = NULL;
bignum_free(p_group14);
p_group14 = NULL;
-#ifdef HAVE_LIBGCRYPT
- gcry_control(GCRYCTL_TERM_SECMEM);
-#elif defined HAVE_LIBCRYPTO
- EVP_cleanup();
- CRYPTO_cleanup_all_ex_data();
-#elif defined HAVE_LIBMBEDTLS
- ssh_mbedtls_cleanup();
-#endif
- ssh_crypto_initialized=0;
- }
+
+ dh_crypto_initialized = 0;
}
int ssh_dh_generate_x(ssh_session session) {
diff --git a/src/init.c b/src/init.c
index bc920f66..f3b6d72c 100644
--- a/src/init.c
+++ b/src/init.c
@@ -51,13 +51,29 @@
* @returns 0 on success, -1 if an error occured.
*/
int ssh_init(void) {
- if(ssh_threads_init())
- return -1;
- if(ssh_crypto_init())
- return -1;
- if(ssh_socket_init())
- return -1;
- return 0;
+ int rc;
+
+ rc = ssh_threads_init();
+ if (rc != SSH_OK) {
+ return -1;
+ }
+
+ rc = ssh_crypto_init();
+ if (rc != SSH_OK) {
+ return -1;
+ }
+
+ rc = ssh_dh_init();
+ if (rc != SSH_OK) {
+ return -1;
+ }
+
+ rc = ssh_socket_init();
+ if (rc != SSH_OK) {
+ return -1;
+ }
+
+ return 0;
}
@@ -70,14 +86,16 @@ int ssh_init(void) {
*
@returns 0 otherwise
*/
-int ssh_finalize(void) {
- ssh_crypto_finalize();
- ssh_socket_cleanup();
- /* It is important to finalize threading after CRYPTO because
- * it still depends on it */
- ssh_threads_finalize();
+int ssh_finalize(void)
+{
+ ssh_dh_finalize();
+ ssh_crypto_finalize();
+ ssh_socket_cleanup();
+ /* It is important to finalize threading after CRYPTO because
+ * it still depends on it */
+ ssh_threads_finalize();
- return 0;
+ return 0;
}
/** @} */
diff --git a/src/libcrypto.c b/src/libcrypto.c
index 846e37e1..b24a18f8 100644
--- a/src/libcrypto.c
+++ b/src/libcrypto.c
@@ -70,6 +70,8 @@ struct ssh_mac_ctx_struct {
} ctx;
};
+static int libcrypto_initialized = 0;
+
void ssh_reseed(void){
#ifndef _WIN32
struct timeval tv;
@@ -787,10 +789,25 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
}
};
-void libcrypto_init(void)
+struct ssh_cipher_struct *ssh_get_ciphertab(void)
+{
+ return ssh_ciphertab;
+}
+
+/**
+ * @internal
+ * @brief Initialize libcrypto's subsystem
+ */
+int ssh_crypto_init(void)
{
size_t i;
+ if (libcrypto_initialized) {
+ return SSH_OK;
+ }
+
+ OpenSSL_add_all_algorithms();
+
for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
int cmp;
@@ -802,11 +819,26 @@ void libcrypto_init(void)
break;
}
}
+
+ libcrypto_initialized = 1;
+
+ return SSH_OK;
}
-struct ssh_cipher_struct *ssh_get_ciphertab(void)
+/**
+ * @internal
+ * @brief Finalize libcrypto's subsystem
+ */
+void ssh_crypto_finalize(void)
{
- return ssh_ciphertab;
+ if (!libcrypto_initialized) {
+ return;
+ }
+
+ EVP_cleanup();
+ CRYPTO_cleanup_all_ex_data();
+
+ libcrypto_initialized = 0;
}
#endif /* LIBCRYPTO */
diff --git a/src/libgcrypt.c b/src/libgcrypt.c
index 0eed44bb..4f21ddab 100644
--- a/src/libgcrypt.c
+++ b/src/libgcrypt.c
@@ -40,6 +40,8 @@ struct ssh_mac_ctx_struct {
gcry_md_hd_t ctx;
};
+static int libgcrypt_initialized = 0;
+
static int alloc_key(struct ssh_cipher_struct *cipher) {
cipher->key = malloc(cipher->keylen);
if (cipher->key == NULL) {
@@ -544,22 +546,6 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
}
};
-void libgcrypt_init(void)
-{
- size_t i;
-
- for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
- int cmp;
- cmp = strcmp(ssh_ciphertab[i].name, "chacha20-poly1305@openssh.com");
- if (cmp == 0) {
- memcpy(&ssh_ciphertab[i],
- ssh_get_chacha20poly1305_cipher(),
- sizeof(struct ssh_cipher_struct));
- break;
- }
- }
-}
-
struct ssh_cipher_struct *ssh_get_ciphertab(void)
{
return ssh_ciphertab;
@@ -615,4 +601,56 @@ fail:
return result;
}
+
+/**
+ * @internal
+ *
+ * @brief Initialize libgcrypt's subsystem
+ */
+int ssh_crypto_init(void)
+{
+ size_t i;
+
+ if (libgcrypt_initialized) {
+ return SSH_OK;
+ }
+
+ gcry_check_version(NULL);
+ if (!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P, 0)) {
+ gcry_control(GCRYCTL_INIT_SECMEM, 4096);
+ gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
+ }
+
+ for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
+ int cmp;
+ cmp = strcmp(ssh_ciphertab[i].name, "chacha20-poly1305@openssh.com");
+ if (cmp == 0) {
+ memcpy(&ssh_ciphertab[i],
+ ssh_get_chacha20poly1305_cipher(),
+ sizeof(struct ssh_cipher_struct));
+ break;
+ }
+ }
+
+ libgcrypt_initialized = 1;
+
+ return SSH_OK;
+}
+
+/**
+ * @internal
+ *
+ * @brief Finalize libgcrypt's subsystem
+ */
+void ssh_crypto_finalize(void)
+{
+ if (!libgcrypt_initialized) {
+ return;
+ }
+
+ gcry_control(GCRYCTL_TERM_SECMEM);
+
+ libgcrypt_initialized = 0;
+}
+
#endif
diff --git a/src/libmbedcrypto.c b/src/libmbedcrypto.c
index 03281f47..10a35270 100644
--- a/src/libmbedcrypto.c
+++ b/src/libmbedcrypto.c
@@ -34,6 +34,7 @@ struct ssh_mac_ctx_struct {
enum ssh_mac_e mac_type;
mbedtls_md_context_t ctx;
};
+static int libmbedcrypto_initialized = 0;
void ssh_reseed(void)
{
@@ -947,11 +948,15 @@ struct ssh_cipher_struct *ssh_get_ciphertab(void)
return ssh_ciphertab;
}
-void ssh_mbedtls_init(void)
+int ssh_crypto_init(void)
{
size_t i;
int rc;
+ if (libmbedcrypto_initialized) {
+ return SSH_OK;
+ }
+
mbedtls_entropy_init(&ssh_mbedtls_entropy);
mbedtls_ctr_drbg_init(&ssh_mbedtls_ctr_drbg);
@@ -972,6 +977,10 @@ void ssh_mbedtls_init(void)
break;
}
}
+
+ libmbedcrypto_initialized = 1;
+
+ return SSH_OK;
}
int ssh_mbedtls_random(void *where, int len, int strong)
@@ -990,10 +999,16 @@ int ssh_mbedtls_random(void *where, int len, int strong)
return !rc;
}
-void ssh_mbedtls_cleanup(void)
+void ssh_crypto_finalize(void)
{
+ if (!libmbedcrypto_initialized) {
+ return;
+ }
+
mbedtls_ctr_drbg_free(&ssh_mbedtls_ctr_drbg);
mbedtls_entropy_free(&ssh_mbedtls_entropy);
+
+ libmbedcrypto_initialized = 0;
}
#endif /* HAVE_LIBMBEDCRYPTO */