diff options
author | Aris Adamantiadis <aris@0xbadc0de.be> | 2015-12-31 10:56:47 +0100 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2018-07-05 12:55:23 +0200 |
commit | 2b40ad29c02da4004dec3a0e51ea8cef4ebac01e (patch) | |
tree | 6f7754b58ac58ec92886a29c08ca7cff97d1d6fc | |
parent | 38c53db9533a3e0ac446ee0a83dac8768d282de9 (diff) | |
download | libssh-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.h | 4 | ||||
-rw-r--r-- | include/libssh/libcrypto.h | 15 | ||||
-rw-r--r-- | include/libssh/libgcrypt.h | 3 | ||||
-rw-r--r-- | include/libssh/libmbedcrypto.h | 2 | ||||
-rw-r--r-- | include/libssh/wrapper.h | 5 | ||||
-rw-r--r-- | src/dh.c | 99 | ||||
-rw-r--r-- | src/init.c | 46 | ||||
-rw-r--r-- | src/libcrypto.c | 38 | ||||
-rw-r--r-- | src/libgcrypt.c | 70 | ||||
-rw-r--r-- | src/libmbedcrypto.c | 19 |
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_ */ @@ -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) { @@ -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 */ |