1
1
libssh/ConfigureChecks.cmake
Jakub Jelen 46090facba libcrypto: Implement OpenSSH-compatible AES-GCM ciphers using OpenSSL
The commit also propares the internals throughout the code base
for the inclusion of a new AEAD cipher, because previously, the
source code counted only with chacha20-poly1305 cipher, which
is very specific in many cases.

The SSH_HMAC_AEAD_GCM mac algorithm is not actually used, but the name
needed to be defined so we can match in the algorithms selection per
OpenSSH specification (MACs are ignored in case GCM is select as a cipher [1]).

If the provided OpenSSL does not provide  EVP_aes_128_gcm()  function,
the AES-GCM ciphers will not be compiled in.

[1] https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL.chacha20poly1305?annotate=HEAD

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-09 12:05:40 +02:00

419 строки
12 KiB
CMake

include(CheckIncludeFile)
include(CheckIncludeFiles)
include(CheckSymbolExists)
include(CheckFunctionExists)
include(CheckLibraryExists)
include(CheckTypeSize)
include(CheckStructHasMember)
include(TestBigEndian)
set(PACKAGE ${PROJECT_NAME})
set(VERSION ${PROJECT_VERSION})
set(DATADIR ${DATA_INSTALL_DIR})
set(LIBDIR ${LIB_INSTALL_DIR})
set(PLUGINDIR "${PLUGIN_INSTALL_DIR}-${LIBRARY_SOVERSION}")
set(SYSCONFDIR ${SYSCONF_INSTALL_DIR})
set(BINARYDIR ${CMAKE_BINARY_DIR})
set(SOURCEDIR ${CMAKE_SOURCE_DIR})
function(COMPILER_DUMPVERSION _OUTPUT_VERSION)
# Remove whitespaces from the argument.
# This is needed for CC="ccache gcc" cmake ..
string(REPLACE " " "" _C_COMPILER_ARG "${CMAKE_C_COMPILER_ARG1}")
execute_process(
COMMAND
${CMAKE_C_COMPILER} ${_C_COMPILER_ARG} -dumpversion
OUTPUT_VARIABLE _COMPILER_VERSION
)
string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2"
_COMPILER_VERSION "${_COMPILER_VERSION}")
set(${_OUTPUT_VERSION} ${_COMPILER_VERSION} PARENT_SCOPE)
endfunction()
if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
compiler_dumpversion(GNUCC_VERSION)
if (NOT GNUCC_VERSION EQUAL 34)
set(CMAKE_REQUIRED_FLAGS "-fvisibility=hidden")
check_c_source_compiles(
"void __attribute__((visibility(\"default\"))) test() {}
int main(void){ return 0; }
" WITH_VISIBILITY_HIDDEN)
unset(CMAKE_REQUIRED_FLAGS)
endif (NOT GNUCC_VERSION EQUAL 34)
endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
# HEADER FILES
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${ARGP_INCLUDE_DIR})
check_include_file(argp.h HAVE_ARGP_H)
unset(CMAKE_REQUIRED_INCLUDES)
check_include_file(pty.h HAVE_PTY_H)
check_include_file(utmp.h HAVE_UTMP_H)
check_include_file(termios.h HAVE_TERMIOS_H)
check_include_file(unistd.h HAVE_UNISTD_H)
check_include_file(stdint.h HAVE_STDINT_H)
check_include_file(util.h HAVE_UTIL_H)
check_include_file(libutil.h HAVE_LIBUTIL_H)
check_include_file(sys/time.h HAVE_SYS_TIME_H)
check_include_file(sys/utime.h HAVE_SYS_UTIME_H)
check_include_file(sys/param.h HAVE_SYS_PARAM_H)
check_include_file(arpa/inet.h HAVE_ARPA_INET_H)
check_include_file(byteswap.h HAVE_BYTESWAP_H)
check_include_file(glob.h HAVE_GLOB_H)
if (WIN32)
check_include_file(io.h HAVE_IO_H)
check_include_files("winsock2.h;ws2tcpip.h;wspiapi.h" HAVE_WSPIAPI_H)
if (NOT HAVE_WSPIAPI_H)
message(STATUS "WARNING: Without wspiapi.h, this build will only work on Windows XP and newer versions")
endif (NOT HAVE_WSPIAPI_H)
check_include_files("winsock2.h;ws2tcpip.h" HAVE_WS2TCPIP_H)
endif (WIN32)
if (OPENSSL_FOUND)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/des.h HAVE_OPENSSL_DES_H)
if (NOT HAVE_OPENSSL_DES_H)
message(FATAL_ERROR "Could not detect openssl/des.h")
endif()
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/aes.h HAVE_OPENSSL_AES_H)
if (NOT HAVE_OPENSSL_AES_H)
message(FATAL_ERROR "Could not detect openssl/aes.h")
endif()
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/ecdh.h HAVE_OPENSSL_ECDH_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/ec.h HAVE_OPENSSL_EC_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file(openssl/ecdsa.h HAVE_OPENSSL_ECDSA_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(EVP_aes_128_ctr HAVE_OPENSSL_EVP_AES_CTR)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(EVP_aes_128_cbc HAVE_OPENSSL_EVP_AES_CBC)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(EVP_aes_128_gcm HAVE_OPENSSL_EVP_AES_GCM)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(CRYPTO_THREADID_set_callback HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(CRYPTO_ctr128_encrypt HAVE_OPENSSL_CRYPTO_CTR128_ENCRYPT)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(EVP_CIPHER_CTX_new HAVE_OPENSSL_EVP_CIPHER_CTX_NEW)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
check_function_exists(RAND_priv_bytes HAVE_OPENSSL_RAND_PRIV_BYTES)
unset(CMAKE_REQUIRED_INCLUDES)
unset(CMAKE_REQUIRED_LIBRARIES)
endif()
if (CMAKE_HAVE_PTHREAD_H)
set(HAVE_PTHREAD_H 1)
endif (CMAKE_HAVE_PTHREAD_H)
if (NOT WITH_GCRYPT AND NOT WITH_MBEDTLS)
if (HAVE_OPENSSL_EC_H AND HAVE_OPENSSL_ECDSA_H)
set(HAVE_OPENSSL_ECC 1)
endif (HAVE_OPENSSL_EC_H AND HAVE_OPENSSL_ECDSA_H)
if (HAVE_OPENSSL_ECC)
set(HAVE_ECC 1)
endif (HAVE_OPENSSL_ECC)
endif ()
if (NOT WITH_MBEDTLS)
set(HAVE_DSA 1)
endif (NOT WITH_MBEDTLS)
# FUNCTIONS
check_function_exists(isblank HAVE_ISBLANK)
check_function_exists(strncpy HAVE_STRNCPY)
check_function_exists(strndup HAVE_STRNDUP)
check_function_exists(strtoull HAVE_STRTOULL)
check_function_exists(explicit_bzero HAVE_EXPLICIT_BZERO)
check_function_exists(memset_s HAVE_MEMSET_S)
if (HAVE_GLOB_H)
check_struct_has_member(glob_t gl_flags glob.h HAVE_GLOB_GL_FLAGS_MEMBER)
check_function_exists(glob HAVE_GLOB)
endif (HAVE_GLOB_H)
if (NOT WIN32)
check_function_exists(vsnprintf HAVE_VSNPRINTF)
check_function_exists(snprintf HAVE_SNPRINTF)
endif (NOT WIN32)
if (WIN32)
check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF)
check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF)
check_symbol_exists(_vsnprintf_s "stdio.h" HAVE__VSNPRINTF_S)
check_symbol_exists(_vsnprintf "stdio.h" HAVE__VSNPRINTF)
check_symbol_exists(_snprintf "stdio.h" HAVE__SNPRINTF)
check_symbol_exists(_snprintf_s "stdio.h" HAVE__SNPRINTF_S)
if (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
check_symbol_exists(ntohll winsock2.h HAVE_NTOHLL)
check_symbol_exists(htonll winsock2.h HAVE_HTONLL)
set(CMAKE_REQUIRED_LIBRARIES ws2_32)
check_symbol_exists(select "winsock2.h;ws2tcpip.h" HAVE_SELECT)
check_symbol_exists(poll "winsock2.h;ws2tcpip.h" HAVE_SELECT)
# The getaddrinfo function is defined to the WspiapiGetAddrInfo inline function
check_symbol_exists(getaddrinfo "winsock2.h;ws2tcpip.h" HAVE_GETADDRINFO)
unset(CMAKE_REQUIRED_LIBRARIES)
endif (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
check_function_exists(_strtoui64 HAVE__STRTOUI64)
set(HAVE_SELECT TRUE)
check_symbol_exists(SecureZeroMemory "windows.h" HAVE_SECURE_ZERO_MEMORY)
else (WIN32)
check_function_exists(poll HAVE_POLL)
check_function_exists(select HAVE_SELECT)
check_function_exists(getaddrinfo HAVE_GETADDRINFO)
check_symbol_exists(ntohll arpa/inet.h HAVE_NTOHLL)
check_symbol_exists(htonll arpa/inet.h HAVE_HTONLL)
endif (WIN32)
if (UNIX)
if (NOT LINUX)
# libsocket (Solaris)
check_library_exists(socket getaddrinfo "" HAVE_LIBSOCKET)
if (HAVE_LIBSOCKET)
set(HAVE_GETADDRINFO TRUE)
set(_REQUIRED_LIBRARIES ${_REQUIRED_LIBRARIES} socket)
endif (HAVE_LIBSOCKET)
# libnsl/inet_pton (Solaris)
check_library_exists(nsl inet_pton "" HAVE_LIBNSL)
if (HAVE_LIBNSL)
set(_REQUIRED_LIBRARIES ${_REQUIRED_LIBRARIES} nsl)
endif (HAVE_LIBNSL)
# librt
check_library_exists(rt nanosleep "" HAVE_LIBRT)
endif (NOT LINUX)
check_library_exists(rt clock_gettime "" HAVE_CLOCK_GETTIME)
if (HAVE_LIBRT OR HAVE_CLOCK_GETTIME)
set(_REQUIRED_LIBRARIES ${_REQUIRED_LIBRARIES} rt)
endif (HAVE_LIBRT OR HAVE_CLOCK_GETTIME)
check_library_exists(util forkpty "" HAVE_LIBUTIL)
check_function_exists(cfmakeraw HAVE_CFMAKERAW)
check_function_exists(__strtoull HAVE___STRTOULL)
endif (UNIX)
set(LIBSSH_REQUIRED_LIBRARIES ${_REQUIRED_LIBRARIES} CACHE INTERNAL "libssh required system libraries")
# LIBRARIES
if (OPENSSL_FOUND)
set(HAVE_LIBCRYPTO 1)
endif (OPENSSL_FOUND)
if (GCRYPT_FOUND)
set(HAVE_LIBGCRYPT 1)
if (GCRYPT_VERSION VERSION_GREATER "1.4.6")
set(HAVE_GCRYPT_ECC 1)
set(HAVE_ECC 1)
endif (GCRYPT_VERSION VERSION_GREATER "1.4.6")
endif (GCRYPT_FOUND)
if (MBEDTLS_FOUND)
set(HAVE_LIBMBEDCRYPTO 1)
set(HAVE_ECC 1)
endif (MBEDTLS_FOUND)
if (CMAKE_USE_PTHREADS_INIT)
set(HAVE_PTHREAD 1)
endif (CMAKE_USE_PTHREADS_INIT)
# OPTIONS
check_c_source_compiles("
__thread int tls;
int main(void) {
return 0;
}" HAVE_GCC_THREAD_LOCAL_STORAGE)
check_c_source_compiles("
__declspec(thread) int tls;
int main(void) {
return 0;
}" HAVE_MSC_THREAD_LOCAL_STORAGE)
###########################################################
# For detecting attributes we need to treat warnings as
# errors
if (UNIX)
# Get warnings for attributs
check_c_compiler_flag("-Wattributs" REQUIRED_FLAGS_WERROR)
if (REQUIRED_FLAGS_WERROR)
set(CMAKE_REQUIRED_FLAGS "-Wattributes")
endif()
# Turn warnings into errors
check_c_compiler_flag("-Werror" REQUIRED_FLAGS_WERROR)
if (REQUIRED_FLAGS_WERROR)
set(CMAKE_REQUIRED_FLAGS "-Werror")
endif()
endif (UNIX)
check_c_source_compiles("
void test_constructor_attribute(void) __attribute__ ((constructor));
void test_constructor_attribute(void)
{
return;
}
int main(void) {
return 0;
}" HAVE_CONSTRUCTOR_ATTRIBUTE)
check_c_source_compiles("
void test_destructor_attribute(void) __attribute__ ((destructor));
void test_destructor_attribute(void)
{
return;
}
int main(void) {
return 0;
}" HAVE_DESTRUCTOR_ATTRIBUTE)
check_c_source_compiles("
#define FALL_THROUGH __attribute__((fallthrough))
int main(void) {
int i = 2;
switch (i) {
case 0:
FALL_THROUGH;
case 1:
break;
default:
break;
}
return 0;
}" HAVE_FALLTHROUGH_ATTRIBUTE)
check_c_source_compiles("
#include <string.h>
int main(void)
{
char buf[] = \"This is some content\";
memset(buf, '\\\\0', sizeof(buf)); __asm__ volatile(\"\" : : \"g\"(&buf) : \"memory\");
return 0;
}" HAVE_GCC_VOLATILE_MEMORY_PROTECTION)
check_c_source_compiles("
#include <stdio.h>
#define __VA_NARG__(...) (__VA_NARG_(_0, ## __VA_ARGS__, __RSEQ_N()) - 1)
#define __VA_NARG_(...) __VA_ARG_N(__VA_ARGS__)
#define __VA_ARG_N( _1, _2, _3, _4, _5, _6, _7, _8, _9,_10,N,...) N
#define __RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#define myprintf(format, ...) printf((format), __VA_NARG__(__VA_ARGS__), __VA_ARGS__)
int main(void) {
myprintf(\"%d %d %d %d\",1,2,3);
return 0;
}" HAVE_GCC_NARG_MACRO)
check_c_source_compiles("
#include <stdio.h>
int main(void) {
printf(\"%s\", __func__);
return 0;
}" HAVE_COMPILER__FUNC__)
check_c_source_compiles("
#include <stdio.h>
int main(void) {
printf(\"%s\", __FUNCTION__);
return 0;
}" HAVE_COMPILER__FUNCTION__)
check_c_source_compiles("
#define ARRAY_LEN 16
void test_attr(const unsigned char *k)
__attribute__((__bounded__(__minbytes__, 2, 16)));
int main(void) {
return 0;
}" HAVE_GCC_BOUNDED_ATTRIBUTE)
# Stop treating warnings as errors
unset(CMAKE_REQUIRED_FLAGS)
# Check for version script support
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map" "VERS_1 {
global: sym;
};
VERS_2 {
global: sym;
} VERS_1;
")
set(CMAKE_REQUIRED_FLAGS "-Wl,--version-script=\"${CMAKE_CURRENT_BINARY_DIR}/conftest.map\"")
check_c_source_compiles("int main(void) { return 0; }" HAVE_LD_VERSION_SCRIPT)
unset(CMAKE_REQUIRED_FLAGS)
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map")
if (WITH_DEBUG_CRYPTO)
set(DEBUG_CRYPTO 1)
endif (WITH_DEBUG_CRYPTO)
if (WITH_DEBUG_PACKET)
set(DEBUG_PACKET 1)
endif (WITH_DEBUG_PACKET)
if (WITH_DEBUG_CALLTRACE)
set(DEBUG_CALLTRACE 1)
endif (WITH_DEBUG_CALLTRACE)
if (WITH_GSSAPI AND NOT GSSAPI_FOUND)
set(WITH_GSSAPI 0)
endif (WITH_GSSAPI AND NOT GSSAPI_FOUND)
# ENDIAN
if (NOT WIN32)
test_big_endian(WORDS_BIGENDIAN)
endif (NOT WIN32)