diff --git a/build/win32/project/Makefile_tls.inc b/build/win32/project/Makefile_tls.inc
index ca13ca2..29615db 100644
--- a/build/win32/project/Makefile_tls.inc
+++ b/build/win32/project/Makefile_tls.inc
@@ -1,7 +1,7 @@
 !IF "$(TLS)" != ""
 
-!	IF "$(TLS)" != "mbedtls" && "$(TLS)" != "gnutls" && "$(TLS)" != "openssl"
-!		ERROR Specified TLS target "$(TLS)" is not supported (supported: mbedtls, gnutls, openssl).
+!	IF "$(TLS)" != "mbedtls" && "$(TLS)" != "mbedtls21" && "$(TLS)" != "gnutls" && "$(TLS)" != "openssl"
+!		ERROR Specified TLS target "$(TLS)" is not supported (supported: mbedtls, mbedtls21, gnutls, openssl).
 !	ENDIF
 
 !	IF "$(TLSINCDIR)" == ""
@@ -20,6 +20,10 @@
 !		IF "$(TLSLIB)" == ""
 !			ERROR Please specify full path to static GnuTLS library (e. g. TLSLIB="\somepath\some.lib").
 !		ENDIF
+!	ELSEIF "$(TLS)" == "mbedtls21"
+!		IF ("$(TLSLIBDIR)" == "" || "$(TLSLIB)" != "" || "$(TLSLIB2)" != "" || "$(TLSLIB3)" != "") && ("$(TLSLIBDIR)" != "" || "$(TLSLIB)" == "" || "$(TLSLIB2)" == "" || "$(TLSLIB3)" == "")
+!			ERROR Please specify either TLSLIBDIR or both TLSLIB, TLSLIB2 and TLSLIB3 (e. g. TLSLIBDIR="\somepath\lib" or TLSLIB="\somepath\mbedtls.lib" TLSLIB2="\somepath\mbedx509.lib" TLSLIB3="\somepath\mbedcrypto.lib").
+!		ENDIF
 !	ELSE
 !		IF ("$(TLSLIBDIR)" == "" && "$(TLSLIB)" == "") || ("$(TLSLIBDIR)" != "" && "$(TLSLIB)" != "")
 !			ERROR Please specify only one of TLSLIBDIR or TLSLIB (e. g. TLSLIBDIR="\somepath\lib" or TLSLIB="\somepath\lib\some.lib").
@@ -44,6 +48,14 @@ ADDMSG =		You may specify path to library using TLSLIB="\somepath\lib\some.lib"
 TLSLIB =		$(TLSLIBDIR)\mbedtls.lib
 !		ENDIF
 CFLAGS =	$(CFLAGS) /DHAVE_POLARSSL
+	### mbed TLS 2.1.x ###
+!	ELSEIF "$(TLS)" == "mbedtls21"
+!		IF "$(TLSLIBDIR)" != ""
+TLSLIB =		$(TLSLIBDIR)\mbedtls.lib
+TLSLIB2 =		$(TLSLIBDIR)\mbedx509.lib
+TLSLIB3 =		$(TLSLIBDIR)\mbedcrypto.lib
+!		ENDIF
+CFLAGS =	$(CFLAGS) /DHAVE_MBEDTLS21
 	### GnuTLS ###
 !	ELSEIF "$(TLS)" == "gnutls"
 CFLAGS =	$(CFLAGS) /DHAVE_GNUTLS
@@ -66,11 +78,16 @@ CFLAGS =	$(CFLAGS) /DHAVE_OPENSSL
 !	IF !EXISTS("$(TLSLIB)")
 !		ERROR TLS library "$(TLSLIB)" not found. $(ADDMSG)
 !	ENDIF
-
-!	IF "$(TLS)" == "openssl"
+!	IF "$(TLS)" == "openssl" || "$(TLS)" == "mbedtls21"
 !		IF !EXISTS("$(TLSLIB2)")
 !			ERROR TLS library "$(TLSLIB2)" not found. $(ADDMSG)
 !		ENDIF
+!		IF "$(TLS)" == "mbedtls21"
+!			IF !EXISTS("$(TLSLIB3)")
+!				ERROR TLS library "$(TLSLIB3)" not found. $(ADDMSG)
+!			ENDIF
+LIBS =		$(LIBS) "$(TLSLIB)" "$(TLSLIB2)" "$(TLSLIB3)"
+!		ENDIF
 LIBS =		$(LIBS) "$(TLSLIB)" "$(TLSLIB2)"
 !	ELSE
 LIBS =		$(LIBS) "$(TLSLIB)"
diff --git a/configure.ac b/configure.ac
index c307137..f7c5223 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1349,7 +1349,7 @@ dnl Check for mbed TLS (PolarSSL) libpolarssl [by default - skip]
 LIBMBEDTLS_CHECK_CONFIG([no])
 if test "x$want_mbedtls" = "xyes"; then
 	if test "x$have_tls" != "xno"; then
-		AC_MSG_ERROR([You can configure for only one TLS library (--with-mbedtls, --with-gnutls or --with-openssl).])
+		AC_MSG_ERROR([You can configure for only one TLS library (--with-mbedtls, --with-mbedtls21, --with-gnutls or --with-openssl).])
 	fi
 
 	if test "x$found_mbedtls" != "xyes"; then
@@ -1364,11 +1364,30 @@ if test "x$want_mbedtls" = "xyes"; then
 	TLS_LIBS="$MBEDTLS_LIBS"
 fi
 
+dnl Check for mbed TLS 2.1.x (PolarSSL) libmbedtls [by default - skip]
+LIBMBEDTLS21_CHECK_CONFIG([no])
+if test "x$want_mbedtls21" = "xyes"; then
+	if test "x$have_tls" != "xno"; then
+		AC_MSG_ERROR([You can configure for only one TLS library (--with-mbedtls, --with-mbedtls21, --with-gnutls or --with-openssl).])
+	fi
+
+	if test "x$found_mbedtls21" != "xyes"; then
+		AC_MSG_ERROR([mbed TLS 2.1.x (PolarSSL) library libmbedtls not found])
+	elif test "x$accept_mbedtls21_version" != "xyes"; then
+		AC_MSG_ERROR([mbed TLS 2.1.x (PolarSSL) library version requirement not met (>= 2.1.9)])
+	else
+		have_tls="mbed TLS 2.1.x"
+	fi
+	TLS_CFLAGS="$MBEDTLS21_CFLAGS"
+	TLS_LDFLAGS="$MBEDTLS21_LDFLAGS"
+	TLS_LIBS="$MBEDTLS21_LIBS"
+fi
+
 dnl Check for GnuTLS libgnutls [by default - skip]
 LIBGNUTLS_CHECK_CONFIG([no])
 if test "x$want_gnutls" = "xyes"; then
 	if test "x$have_tls" != "xno"; then
-		AC_MSG_ERROR([You can configure for only one TLS library (--with-mbedtls, --with-gnutls or --with-openssl).])
+		AC_MSG_ERROR([You can configure for only one TLS library (--with-mbedtls, --with-mbedtls21, --with-gnutls or --with-openssl).])
 	fi
 
 	if test "x$found_gnutls" != "xyes"; then
@@ -1387,7 +1406,7 @@ dnl Check for OpenSSL libssl and libcrypto [by default - skip]
 LIBOPENSSL_CHECK_CONFIG([no])
 if test "x$want_openssl" = "xyes"; then
 	if test "x$have_tls" != "xno"; then
-		AC_MSG_ERROR([You can configure for only one TLS library (--with-mbedtls, --with-gnutls or --with-openssl).])
+		AC_MSG_ERROR([You can configure for only one TLS library (--with-mbedtls, --with-mbedtls21, --with-gnutls or --with-openssl).])
 	fi
 
 	if test "x$found_openssl" != "xyes"; then
diff --git a/include/comms.h b/include/comms.h
index 11d875e..7b23f95 100644
--- a/include/comms.h
+++ b/include/comms.h
@@ -72,7 +72,7 @@ zbx_buf_type_t;
 #define ZBX_SOCKET_COUNT	256
 #define ZBX_STAT_BUF_LEN	2048
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 typedef struct zbx_tls_context	zbx_tls_context_t;
 #endif
 
@@ -83,7 +83,7 @@ typedef struct
 	size_t				read_bytes;
 	char				*buffer;
 	char				*next_line;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_context_t		*tls_ctx;
 #endif
 	unsigned int 			connection_type;	/* type of connection actually established: */
diff --git a/include/dbcache.h b/include/dbcache.h
index 73a5d8d..c278ad4 100644
--- a/include/dbcache.h
+++ b/include/dbcache.h
@@ -110,7 +110,7 @@ typedef struct
 	unsigned char	status;
 	unsigned char	tls_connect;
 	unsigned char	tls_accept;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	char		tls_issuer[HOST_TLS_ISSUER_LEN_MAX];
 	char		tls_subject[HOST_TLS_SUBJECT_LEN_MAX];
 	char		tls_psk_identity[HOST_TLS_PSK_IDENTITY_LEN_MAX];
@@ -420,7 +420,7 @@ void	DCrequeue_proxy(zbx_uint64_t hostid, unsigned char update_nextcheck);
 void	DCconfig_set_proxy_timediff(zbx_uint64_t hostid, const zbx_timespec_t *timediff);
 int	DCcheck_proxy_permissions(const char *host, const zbx_socket_t *sock, zbx_uint64_t *hostid, char **error);
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 size_t	DCget_psk_by_identity(const unsigned char *psk_identity, unsigned char *psk_buf, size_t psk_buf_len);
 #endif
 
diff --git a/include/zbxnix.h b/include/zbxnix.h
index cba7e2b..b0e5767 100644
--- a/include/zbxnix.h
+++ b/include/zbxnix.h
@@ -20,7 +20,7 @@
 #ifndef ZABBIX_ZBXNIX_H
 #define ZABBIX_ZBXNIX_H
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 int	zbx_coredump_disable(void);
 #endif
 
diff --git a/m4/libmbedtls21.m4 b/m4/libmbedtls21.m4
new file mode 100644
index 0000000..61c0dbb
--- /dev/null
+++ b/m4/libmbedtls21.m4
@@ -0,0 +1,148 @@
+# mbed TLS 2.1.x (PolarSSL) LIBMBEDTLS21_CHECK_CONFIG ([DEFAULT-ACTION])
+# ----------------------------------------------------------
+# Derived from libssh2.m4 written by
+#    Alexander Vladishev                      Oct-26-2009
+#    Dmitry Borovikov                         Feb-13-2010
+#
+# Checks for mbed TLS 2.1.x (PolarSSL) library libmbedtls.  DEFAULT-ACTION
+# is the string yes or no to specify whether to default to --with-mbedtls21 or
+# --without-mbedtls21. If not supplied, DEFAULT-ACTION is no.
+#
+# This macro #defines HAVE_MBEDTLS21 if a required header files are
+# found, and sets @MBEDTLS21_LDFLAGS@, @MBEDTLS21_CFLAGS@ and @MBEDTLS21_LIBS@
+# to the necessary values.
+#
+# Users may override the detected values by doing something like:
+# MBEDTLS21_LIBS="-lmbedtls -lmbedx509 -lmbedcrypto" MBEDTLS21_CFLAGS="-I/usr/myinclude" ./configure
+#
+# This macro is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+AC_DEFUN([LIBMBEDTLS21_TRY_LINK],
+[
+AC_TRY_LINK(
+[
+#include <mbedtls/ssl.h>
+],
+[
+	mbedtls_ssl_context	ssl;
+
+	mbedtls_ssl_init(&ssl);
+],
+found_mbedtls21="yes",)
+])dnl
+
+AC_DEFUN([LIBMBEDTLS21_ACCEPT_VERSION],
+[
+	# Zabbix minimal supported version of libmbedtls:
+	minimal_mbedtls21_version_major=2
+	minimal_mbedtls21_version_minor=1
+	minimal_mbedtls21_version_patch=9
+
+	# get version
+	found_mbedtls21_version_major=`cat $1 | $EGREP \#define.*MBEDTLS_VERSION_MAJOR | $AWK '{print @S|@3;}'`
+	found_mbedtls21_version_minor=`cat $1 | $EGREP \#define.*MBEDTLS_VERSION_MINOR | $AWK '{print @S|@3;}'`
+	found_mbedtls21_version_patch=`cat $1 | $EGREP \#define.*MBEDTLS_VERSION_PATCH | $AWK '{print @S|@3;}'`
+
+	if test $((found_mbedtls21_version_major)) -gt $((minimal_mbedtls21_version_major)); then
+		accept_mbedtls21_version="yes"
+	elif test $((found_mbedtls21_version_major)) -lt $((minimal_mbedtls21_version_major)); then
+		accept_mbedtls21_version="no"
+	elif test $((found_mbedtls21_version_minor)) -gt $((minimal_mbedtls21_version_minor)); then
+		accept_mbedtls21_version="yes"
+	elif test $((found_mbedtls21_version_minor)) -lt $((minimal_mbedtls21_version_minor)); then
+		accept_mbedtls21_version="no"
+	elif test $((found_mbedtls21_version_patch)) -ge $((minimal_mbedtls21_version_patch)); then
+		accept_mbedtls21_version="yes"
+	else
+		accept_mbedtls21_version="no"
+	fi;
+])dnl
+
+AC_DEFUN([LIBMBEDTLS21_CHECK_CONFIG],
+[
+  AC_ARG_WITH(mbedtls21,[
+If you want to use encryption provided by mbed TLS 2.1.x (PolarSSL) library:
+AC_HELP_STRING([--with-mbedtls21@<:@=DIR@:>@],[use mbed TLS 2.1.x (PolarSSL) package @<:@default=no@:>@, DIR is the libmbedtls install directory.])],
+    [
+	if test "$withval" = "no"; then
+	    want_mbedtls21="no"
+	    _libmbedtls21_dir="no"
+	elif test "$withval" = "yes"; then
+	    want_mbedtls21="yes"
+	    _libmbedtls21_dir="no"
+	else
+	    want_mbedtls21="yes"
+	    _libmbedtls21_dir=$withval
+	fi
+	accept_mbedtls21_version="no"
+    ],[want_mbedtls21=ifelse([$1],,[no],[$1])]
+  )
+
+  if test "x$want_mbedtls21" = "xyes"; then
+     AC_MSG_CHECKING(for mbed TLS 2.1.x (PolarSSL) support)
+
+     if test "x$_libmbedtls21_dir" = "xno"; then
+       if test -f /usr/local/include/mbedtls/version.h; then
+         MBEDTLS21_CFLAGS=-I/usr/local/include
+         MBEDTLS21_LDFLAGS=-L/usr/local/lib
+         MBEDTLS21_LIBS="-lmbedtls -lmbedx509 -lmbedcrypto"
+         found_mbedtls21="yes"
+         LIBMBEDTLS21_ACCEPT_VERSION([/usr/local/include/mbedtls/version.h])
+       elif test -f /usr/include/mbedtls/version.h; then
+         MBEDTLS21_CFLAGS=-I/usr/include
+         MBEDTLS21_LDFLAGS=-L/usr/lib
+         MBEDTLS21_LIBS="-lmbedtls -lmbedx509 -lmbedcrypto"
+         found_mbedtls21="yes"
+         LIBMBEDTLS21_ACCEPT_VERSION([/usr/include/mbedtls/version.h])
+       else			# libraries are not found in default directories
+         found_mbedtls21="no"
+         AC_MSG_RESULT(no)
+       fi
+     else
+       if test -f $_libmbedtls21_dir/include/mbedtls/version.h; then
+         MBEDTLS21_CFLAGS=-I$_libmbedtls21_dir/include
+         MBEDTLS21_LDFLAGS=-L$_libmbedtls21_dir/lib
+         MBEDTLS21_LIBS="-lmbedtls -lmbedx509 -lmbedcrypto"
+         found_mbedtls21="yes"
+         LIBMBEDTLS21_ACCEPT_VERSION([$_libmbedtls21_dir/include/mbedtls/version.h])
+       else
+         found_mbedtls21="no"
+         AC_MSG_RESULT(no)
+       fi
+     fi
+  fi
+
+  if test "x$found_mbedtls21" = "xyes"; then
+    am_save_cflags="$CFLAGS"
+    am_save_ldflags="$LDFLAGS"
+    am_save_libs="$LIBS"
+
+    CFLAGS="$CFLAGS $MBEDTLS21_CFLAGS"
+    LDFLAGS="$LDFLAGS $MBEDTLS21_LDFLAGS"
+    LIBS="$LIBS $MBEDTLS21_LIBS"
+
+    found_mbedtls21="no"
+    LIBMBEDTLS21_TRY_LINK([no])
+
+    CFLAGS="$am_save_cflags"
+    LDFLAGS="$am_save_ldflags"
+    LIBS="$am_save_libs"
+
+    if test "x$found_mbedtls21" = "xyes"; then
+      AC_DEFINE([HAVE_MBEDTLS21], 1, [Define to 1 if you have the 'libmbedtls' 2.1.x library (-lmbedtls -lmbedx509 -lmbedcrypto)])
+      AC_MSG_RESULT(yes)
+    else
+      AC_MSG_RESULT(no)
+      MBEDTLS21_CFLAGS=""
+      MBEDTLS21_LDFLAGS=""
+      MBEDTLS21_LIBS=""
+    fi
+  fi
+
+  AC_SUBST(MBEDTLS21_CFLAGS)
+  AC_SUBST(MBEDTLS21_LDFLAGS)
+  AC_SUBST(MBEDTLS21_LIBS)
+
+])dnl
diff --git a/src/libs/zbxcomms/comms.c b/src/libs/zbxcomms/comms.c
index 213788a..3f31cec 100644
--- a/src/libs/zbxcomms/comms.c
+++ b/src/libs/zbxcomms/comms.c
@@ -439,7 +439,7 @@ static int	zbx_socket_create(zbx_socket_t *s, int type, const char *source_ip, c
 		THIS_SHOULD_NEVER_HAPPEN;
 		return FAIL;
 	}
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	if (ZBX_TCP_SEC_TLS_PSK == tls_connect && '\0' == *tls_arg1)
 	{
 		zbx_set_socket_strerror("cannot connect with PSK: PSK not available");
@@ -510,7 +510,7 @@ static int	zbx_socket_create(zbx_socket_t *s, int type, const char *source_ip, c
 		goto out;
 	}
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	if ((ZBX_TCP_SEC_TLS_CERT == tls_connect || ZBX_TCP_SEC_TLS_PSK == tls_connect) &&
 			SUCCEED != zbx_tls_connect(s, tls_connect, tls_arg1, tls_arg2, &error))
 	{
@@ -546,7 +546,7 @@ static int	zbx_socket_create(zbx_socket_t *s, int type, const char *source_ip, c
 		THIS_SHOULD_NEVER_HAPPEN;
 		return FAIL;
 	}
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	if (ZBX_TCP_SEC_TLS_PSK == tls_connect && '\0' == *tls_arg1)
 	{
 		zbx_set_socket_strerror("cannot connect with PSK: PSK not available");
@@ -620,7 +620,7 @@ static int	zbx_socket_create(zbx_socket_t *s, int type, const char *source_ip, c
 		return FAIL;
 	}
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	if ((ZBX_TCP_SEC_TLS_CERT == tls_connect || ZBX_TCP_SEC_TLS_PSK == tls_connect) &&
 			SUCCEED != zbx_tls_connect(s, tls_connect, tls_arg1, tls_arg2, &error))
 	{
@@ -653,13 +653,13 @@ static ssize_t	zbx_tcp_write(zbx_socket_t *s, const char *buf, size_t len)
 {
 	ssize_t	res;
 	int	err;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	char	*error = NULL;
 #endif
 #if defined(_WINDOWS)
 	double	sec;
 #endif
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	if (NULL != s->tls_ctx)	/* TLS connection */
 	{
 		if (ZBX_PROTO_ERROR == (res = zbx_tls_write(s, buf, len, &error)))
@@ -1232,7 +1232,7 @@ int	zbx_tcp_accept(zbx_socket_t *s, unsigned int tls_accept)
 	/* if the 1st byte is 0x16 then assume it's a TLS connection */
 	if (1 == res && '\x16' == buf)
 	{
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		if (0 != (tls_accept & (ZBX_TCP_SEC_TLS_CERT | ZBX_TCP_SEC_TLS_PSK)))
 		{
 			char	*error = NULL;
@@ -1287,7 +1287,7 @@ out:
  ******************************************************************************/
 void	zbx_tcp_unaccept(zbx_socket_t *s)
 {
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_close(s);
 #endif
 	if (!s->accepted) return;
@@ -1468,7 +1468,7 @@ static ssize_t	zbx_tcp_read(zbx_socket_t *s, char *buf, size_t len)
 #if defined(_WINDOWS)
 	double	sec;
 #endif
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	if (NULL != s->tls_ctx)	/* TLS connection */
 	{
 		char	*error = NULL;
diff --git a/src/libs/zbxcrypto/tls.c b/src/libs/zbxcrypto/tls.c
index 7338883..b720452 100644
--- a/src/libs/zbxcrypto/tls.c
+++ b/src/libs/zbxcrypto/tls.c
@@ -19,7 +19,7 @@
 
 #include "common.h"
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 
 #include "comms.h"
 #include "threads.h"
@@ -36,6 +36,15 @@
 #	include <polarssl/debug.h>
 #	include <polarssl/oid.h>
 #	include <polarssl/version.h>
+#elif defined(HAVE_MBEDTLS21)
+#	include <mbedtls/entropy.h>
+#	include <mbedtls/ctr_drbg.h>
+#	include <mbedtls/ssl.h>
+#	include <mbedtls/error.h>
+#	include <mbedtls/debug.h>
+#	include <mbedtls/oid.h>
+#	include <mbedtls/net.h>
+#	include <mbedtls/version.h>
 #elif defined(HAVE_GNUTLS)
 #	include <gnutls/gnutls.h>
 #	include <gnutls/x509.h>
@@ -55,6 +64,14 @@
 #	define ZBX_TLS_CIPHERSUITE_CERT	0			/* select only certificate ciphersuites */
 #	define ZBX_TLS_CIPHERSUITE_PSK	1			/* select only pre-shared key ciphersuites */
 #	define ZBX_TLS_CIPHERSUITE_ALL	2			/* select ciphersuites with certificate and PSK */
+#elif defined(HAVE_MBEDTLS21)
+#	define ZBX_TLS_MIN_MAJOR_VER	MBEDTLS_SSL_MAJOR_VERSION_3
+#	define ZBX_TLS_MIN_MINOR_VER	MBEDTLS_SSL_MINOR_VERSION_3
+#	define ZBX_TLS_MAX_MAJOR_VER	MBEDTLS_SSL_MAJOR_VERSION_3
+#	define ZBX_TLS_MAX_MINOR_VER	MBEDTLS_SSL_MINOR_VERSION_3
+#	define ZBX_TLS_CIPHERSUITE_CERT	0			/* select only certificate ciphersuites */
+#	define ZBX_TLS_CIPHERSUITE_PSK	1			/* select only pre-shared key ciphersuites */
+#	define ZBX_TLS_CIPHERSUITE_ALL	2			/* select ciphersuites with certificate and PSK */
 #endif
 
 #if defined(HAVE_OPENSSL) && OPENSSL_VERSION_NUMBER < 0x1010000fL	/* for OpenSSL 1.0.1/1.0.2 (before 1.1.0) */
@@ -153,6 +170,9 @@ struct zbx_tls_context
 {
 #if defined(HAVE_POLARSSL)
 	ssl_context			*ctx;
+#elif defined(HAVE_MBEDTLS21)
+	mbedtls_ssl_config			*conf;
+	mbedtls_ssl_context			*ctx;
 #elif defined(HAVE_GNUTLS)
 	gnutls_session_t		ctx;
 	gnutls_psk_client_credentials_t	psk_client_creds;
@@ -202,6 +222,17 @@ ZBX_THREAD_LOCAL static char			*err_msg		= NULL;
 ZBX_THREAD_LOCAL static int			*ciphersuites_cert	= NULL;
 ZBX_THREAD_LOCAL static int			*ciphersuites_psk	= NULL;
 ZBX_THREAD_LOCAL static int			*ciphersuites_all	= NULL;
+#elif defined(HAVE_MBEDTLS21)
+ZBX_THREAD_LOCAL static mbedtls_x509_crt		*ca_cert		= NULL;
+ZBX_THREAD_LOCAL static mbedtls_x509_crl		*crl			= NULL;
+ZBX_THREAD_LOCAL static mbedtls_x509_crt		*my_cert		= NULL;
+ZBX_THREAD_LOCAL static mbedtls_pk_context		*my_priv_key		= NULL;
+ZBX_THREAD_LOCAL static mbedtls_entropy_context		*entropy		= NULL;
+ZBX_THREAD_LOCAL static mbedtls_ctr_drbg_context	*ctr_drbg		= NULL;
+ZBX_THREAD_LOCAL static char			*err_msg		= NULL;
+ZBX_THREAD_LOCAL static int			*ciphersuites_cert	= NULL;
+ZBX_THREAD_LOCAL static int			*ciphersuites_psk	= NULL;
+ZBX_THREAD_LOCAL static int			*ciphersuites_all	= NULL;
 #elif defined(HAVE_GNUTLS)
 ZBX_THREAD_LOCAL static gnutls_certificate_credentials_t	my_cert_creds		= NULL;
 ZBX_THREAD_LOCAL static gnutls_psk_client_credentials_t		my_psk_client_creds	= NULL;
@@ -235,8 +266,7 @@ ZBX_THREAD_LOCAL char				info_buf[256];
  * Comments:                                                                      *
  *     For more information about why and how to use personalization strings see  *
  *     https://polarssl.org/module-level-design-rng                               *
- *     http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf *
- *                                                                                *
+ *     http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP *                                                                                *
  **********************************************************************************/
 static void	zbx_make_personalization_string(unsigned char pers[64])
 {
@@ -258,6 +288,39 @@ static void	zbx_make_personalization_string(unsigned char pers[64])
 	sha512_finish(&ctx, pers);
 	sha512_free(&ctx);
 }
+#elif defined(HAVE_MBEDTLS21)
+/**********************************************************************************
+ *                                                                                *
+ * Function: zbx_make_personalization_string                                      *
+ *                                                                                *
+ * Purpose: provide additional entropy for initialization of crypto library       *
+ *                                                                                *
+ * Comments:                                                                      *
+ *     For more information about why and how to use personalization strings see  *
+ *     https://polarssl.org/module-level-design-rng                               *
+ *     http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf *
+ *                                                                                *
+ **********************************************************************************/
+static void	zbx_make_personalization_string(unsigned char pers[64])
+{
+	long int	thread_id;
+	zbx_timespec_t	ts;
+	mbedtls_sha512_context	ctx;
+
+	mbedtls_sha512_init(&ctx);
+	mbedtls_sha512_starts(&ctx, 1);		/* use SHA-384 mode */
+
+	thread_id = zbx_get_thread_id();
+	mbedtls_sha512_update(&ctx, (const unsigned char *)&thread_id, sizeof(thread_id));
+
+	zbx_timespec(&ts);
+
+	if (0 != ts.ns)
+		mbedtls_sha512_update(&ctx, (const unsigned char *)&ts.ns, sizeof(ts.ns));
+
+	mbedtls_sha512_finish(&ctx, pers);
+	mbedtls_sha512_free(&ctx);
+}
 #endif
 
 #if defined(HAVE_POLARSSL)
@@ -281,6 +344,27 @@ static void	polarssl_debug_cb(void *tls_ctx, int level, const char *str)
 	zbx_rtrim(msg, "\n");
 	zabbix_log(LOG_LEVEL_TRACE, "PolarSSL debug: level=%d \"%s\"", level, msg);
 }
+#elif defined(HAVE_MBEDTLS21)
+/******************************************************************************
+ *                                                                            *
+ * Function: polarssl_debug_cb                                                *
+ *                                                                            *
+ * Purpose: write a PolarSSL debug message into Zabbix log                    *
+ *                                                                            *
+ * Comments:                                                                  *
+ *     Parameter 'tls_ctx' is not used but cannot be removed because this is  *
+ *     a callback function, its arguments are defined in PolarSSL.            *
+ *                                                                            *
+ ******************************************************************************/
+static void	polarssl_debug_cb(void *tls_ctx, int level, const char *filename, int lineno, const char *str)
+{
+	char	msg[1024];	/* Apparently 1024 bytes is the longest message which can come from PolarSSL 1.3.9 */
+
+	/* remove '\n' from the end of debug message */
+	zbx_strlcpy(msg, str, sizeof(msg));
+	zbx_rtrim(msg, "\n");
+	zabbix_log(LOG_LEVEL_TRACE, "PolarSSL debug: level=%d filename=%s lineno=%d \"%s\"", level, filename, lineno, msg);
+}
 #elif defined(HAVE_GNUTLS)
 /******************************************************************************
  *                                                                            *
@@ -392,6 +476,14 @@ static void	zbx_tls_error_msg(int error_code, const char *msg, char **error)
 	polarssl_strerror(error_code, err, sizeof(err));
 	*error = zbx_dsprintf(*error, "%s%s", msg, err);
 }
+#elif defined(HAVE_MBEDTLS21)
+static void	zbx_tls_error_msg(int error_code, const char *msg, char **error)
+{
+	char	err[128];	/* 128 bytes are enough for PolarSSL error messages */
+
+	mbedtls_strerror(error_code, err, sizeof(err));
+	*error = zbx_dsprintf(*error, "%s%s", msg, err);
+}
 #elif defined(HAVE_OPENSSL)
 void	zbx_tls_error_msg(char **error, size_t *error_alloc, size_t *error_offset)
 {
@@ -469,6 +561,58 @@ static void	zbx_tls_cert_error_msg(unsigned int flags, char **error)
 		i++;
 	}
 }
+#elif defined(HAVE_MBEDTLS21)
+/******************************************************************************
+ *                                                                            *
+ * Function: zbx_tls_cert_error_msg                                           *
+ *                                                                            *
+ * Purpose:                                                                   *
+ *     compose a certificate validation error message by decoding PolarSSL    *
+ *     mbedtls_ssl_get_verify_result() return value                           *
+ *                                                                            *
+ * Parameters:                                                                *
+ *     flags   - [IN] result returned by PolarSSL                             *
+ *                    mbedtls_ssl_get_verify_result()                         *
+ *     error   - [OUT] dynamically allocated memory with error message        *
+ *                                                                            *
+ ******************************************************************************/
+static void	zbx_tls_cert_error_msg(unsigned int flags, char **error)
+{
+	const unsigned int	bits[] = { MBEDTLS_X509_BADCERT_EXPIRED, MBEDTLS_X509_BADCERT_REVOKED, MBEDTLS_X509_BADCERT_CN_MISMATCH,
+				MBEDTLS_X509_BADCERT_NOT_TRUSTED, MBEDTLS_X509_BADCRL_NOT_TRUSTED,
+				MBEDTLS_X509_BADCRL_EXPIRED, MBEDTLS_X509_BADCERT_MISSING, MBEDTLS_X509_BADCERT_SKIP_VERIFY, MBEDTLS_X509_BADCERT_OTHER,
+				MBEDTLS_X509_BADCERT_FUTURE, MBEDTLS_X509_BADCRL_FUTURE,
+				MBEDTLS_X509_BADCERT_KEY_USAGE, MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, MBEDTLS_X509_BADCERT_NS_CERT_TYPE,
+				0 };
+	const char		*msgs[] = { "expired", "revoked", "Common Name mismatch",
+				"self-signed or not signed by trusted CA", "CRL not signed by trusted CA",
+				"CRL expired", "certificate missing", "verification skipped", "other reason",
+				"validity starts in future", "CRL validity starts in future"
+				, "actual use does not match keyUsage extension",
+				"actual use does not match extendedKeyUsage extension",
+				"actual use does not match nsCertType extension"
+				};
+	int			i = 0, k = 0;
+
+	*error = zbx_strdup(*error, "invalid peer certificate: ");
+
+	while (0 != flags && 0 != bits[i])
+	{
+		if (0 != (flags & bits[i]))
+		{
+			flags &= ~bits[i];	/* reset the checked bit to detect no-more-set-bits without checking */
+						/* every bit */
+			if (0 != k)
+				*error = zbx_strdcat(*error, ", ");
+			else
+				k = 1;
+
+			*error = zbx_strdcat(*error, msgs[i]);
+		}
+
+		i++;
+	}
+}
 #endif
 
 /******************************************************************************
@@ -1074,6 +1218,171 @@ static unsigned int	zbx_ciphersuites(int type, int **suites)
 
 	return count;
 }
+#elif defined(HAVE_MBEDTLS21)
+/******************************************************************************
+ *                                                                            *
+ * Function: zbx_is_ciphersuite_cert                                          *
+ *                                                                            *
+ * Purpose: does the specified ciphersuite ID refer to a non-PSK              *
+ *          (i.e. certificate) ciphersuite supported for the specified TLS    *
+ *          version range                                                     *
+ *                                                                            *
+ * Comments:                                                                  *
+ *          RFC 7465 "Prohibiting RC4 Cipher Suites" requires that RC4 should *
+ *          never be used. Also, discard weak encryptions.                    *
+ *                                                                            *
+ ******************************************************************************/
+static int	zbx_is_ciphersuite_cert(const int *p)
+{
+	const mbedtls_ssl_ciphersuite_t	*info;
+
+	/* PolarSSL function mbedtls_ssl_ciphersuite_uses_psk() is not used here because it can be unavailable in some */
+	/* installations. */
+	if (NULL != (info = mbedtls_ssl_ciphersuite_from_id(*p)) && (MBEDTLS_KEY_EXCHANGE_ECDHE_RSA == info->key_exchange ||
+			MBEDTLS_KEY_EXCHANGE_RSA == info->key_exchange) &&
+			(MBEDTLS_CIPHER_AES_128_GCM == info->cipher || MBEDTLS_CIPHER_AES_128_CBC == info->cipher) &&
+			0 == (info->flags & MBEDTLS_CIPHERSUITE_WEAK) &&
+			(ZBX_TLS_MIN_MAJOR_VER > info->min_major_ver || (ZBX_TLS_MIN_MAJOR_VER == info->min_major_ver &&
+			ZBX_TLS_MIN_MINOR_VER >= info->min_minor_ver)) &&
+			(ZBX_TLS_MAX_MAJOR_VER < info->max_major_ver || (ZBX_TLS_MAX_MAJOR_VER == info->max_major_ver &&
+			ZBX_TLS_MAX_MINOR_VER <= info->max_minor_ver)))
+	{
+		return SUCCEED;
+	}
+	else
+		return FAIL;
+}
+
+/******************************************************************************
+ *                                                                            *
+ * Function: zbx_is_ciphersuite_psk                                           *
+ *                                                                            *
+ * Purpose: does the specified ciphersuite ID refer to a PSK ciphersuite      *
+ *          supported for the specified TLS version range                     *
+ *                                                                            *
+ * Comments:                                                                  *
+ *          RFC 7465 "Prohibiting RC4 Cipher Suites" requires that RC4 should *
+ *          never be used. Also, discard weak encryptions.                    *
+ *                                                                            *
+ ******************************************************************************/
+static int	zbx_is_ciphersuite_psk(const int *p)
+{
+	const mbedtls_ssl_ciphersuite_t	*info;
+
+	if (NULL != (info = mbedtls_ssl_ciphersuite_from_id(*p)) && (MBEDTLS_KEY_EXCHANGE_ECDHE_PSK == info->key_exchange ||
+			MBEDTLS_KEY_EXCHANGE_PSK == info->key_exchange) &&
+			(MBEDTLS_CIPHER_AES_128_GCM == info->cipher || MBEDTLS_CIPHER_AES_128_CBC == info->cipher) &&
+			0 == (info->flags & MBEDTLS_CIPHERSUITE_WEAK) &&
+			(ZBX_TLS_MIN_MAJOR_VER > info->min_major_ver || (ZBX_TLS_MIN_MAJOR_VER == info->min_major_ver &&
+			ZBX_TLS_MIN_MINOR_VER >= info->min_minor_ver)) &&
+			(ZBX_TLS_MAX_MAJOR_VER < info->max_major_ver || (ZBX_TLS_MAX_MAJOR_VER == info->max_major_ver &&
+			ZBX_TLS_MAX_MINOR_VER <= info->max_minor_ver)))
+	{
+		return SUCCEED;
+	}
+	else
+		return FAIL;
+}
+
+/******************************************************************************
+ *                                                                            *
+ * Function: zbx_is_ciphersuite_all                                           *
+ *                                                                            *
+ * Purpose: does the specified ciphersuite ID refer to a good ciphersuite     *
+ *          supported for the specified TLS version range                     *
+ *                                                                            *
+ * Comments:                                                                  *
+ *          RFC 7465 "Prohibiting RC4 Cipher Suites" requires that RC4 should *
+ *          never be used. Also, discard weak encryptions.                    *
+ *                                                                            *
+ ******************************************************************************/
+static int	zbx_is_ciphersuite_all(const int *p)
+{
+	const mbedtls_ssl_ciphersuite_t	*info;
+
+	if (NULL != (info = mbedtls_ssl_ciphersuite_from_id(*p)) && (MBEDTLS_KEY_EXCHANGE_ECDHE_RSA == info->key_exchange ||
+			MBEDTLS_KEY_EXCHANGE_RSA == info->key_exchange ||
+			MBEDTLS_KEY_EXCHANGE_ECDHE_PSK == info->key_exchange ||
+			MBEDTLS_KEY_EXCHANGE_PSK == info->key_exchange) &&
+			(MBEDTLS_CIPHER_AES_128_GCM == info->cipher || MBEDTLS_CIPHER_AES_128_CBC == info->cipher) &&
+			0 == (info->flags & MBEDTLS_CIPHERSUITE_WEAK) &&
+			(ZBX_TLS_MIN_MAJOR_VER > info->min_major_ver || (ZBX_TLS_MIN_MAJOR_VER == info->min_major_ver &&
+			ZBX_TLS_MIN_MINOR_VER >= info->min_minor_ver)) &&
+			(ZBX_TLS_MAX_MAJOR_VER < info->max_major_ver || (ZBX_TLS_MAX_MAJOR_VER == info->max_major_ver &&
+			ZBX_TLS_MAX_MINOR_VER <= info->max_minor_ver)))
+	{
+		return SUCCEED;
+	}
+	else
+		return FAIL;
+}
+
+/******************************************************************************
+ *                                                                            *
+ * Function: zbx_ciphersuites                                                 *
+ *                                                                            *
+ * Purpose: copy a list of ciphersuites (certificate or PSK-related) from a   *
+ *          list of all supported ciphersuites                                *
+ *                                                                            *
+ ******************************************************************************/
+static unsigned int	zbx_ciphersuites(int type, int **suites)
+{
+	const int	*supported_suites, *p;
+	int		*q;
+	unsigned int	count = 0;
+
+	supported_suites = mbedtls_ssl_list_ciphersuites();
+
+	/* count available relevant ciphersuites */
+	for (p = supported_suites; 0 != *p; p++)
+	{
+		if (ZBX_TLS_CIPHERSUITE_CERT == type)
+		{
+			if (SUCCEED != zbx_is_ciphersuite_cert(p))
+				continue;
+		}
+		else if (ZBX_TLS_CIPHERSUITE_PSK == type)
+		{
+			if (SUCCEED != zbx_is_ciphersuite_psk(p))
+				continue;
+		}
+		else	/* ZBX_TLS_CIPHERSUITE_ALL */
+		{
+			if (SUCCEED != zbx_is_ciphersuite_all(p))
+				continue;
+		}
+
+		count++;
+	}
+
+	*suites = zbx_malloc(*suites, (count + 1) * sizeof(int));
+
+	/* copy the ciphersuites into array */
+	for (p = supported_suites, q = *suites; 0 != *p; p++)
+	{
+		if (ZBX_TLS_CIPHERSUITE_CERT == type)
+		{
+			if (SUCCEED != zbx_is_ciphersuite_cert(p))
+				continue;
+		}
+		else if (ZBX_TLS_CIPHERSUITE_PSK == type)
+		{
+			if (SUCCEED != zbx_is_ciphersuite_psk(p))
+				continue;
+		}
+		else	/* ZBX_TLS_CIPHERSUITE_ALL */
+		{
+			if (SUCCEED != zbx_is_ciphersuite_all(p))
+				continue;
+		}
+
+		*q++ = *p;
+	}
+
+	*q = 0;
+
+	return count;
+}
 #endif
 
 /******************************************************************************
@@ -1228,23 +1537,123 @@ static int	zbx_psk_cb(void *par, ssl_context *tls_ctx, const unsigned char *psk_
 
 	return -1;
 }
-#elif defined(HAVE_GNUTLS)
+#elif defined(HAVE_MBEDTLS21)
 /******************************************************************************
  *                                                                            *
  * Function: zbx_psk_cb                                                       *
  *                                                                            *
  * Purpose:                                                                   *
- *     find and set the requested pre-shared key upon GnuTLS request          *
+ *     find and set the requested pre-shared key upon PolarSSL request        *
  *                                                                            *
  * Parameters:                                                                *
- *     session      - [IN] not used                                           *
- *     psk_identity - [IN] PSK identity for which the PSK should be searched  *
- *                         and set                                            *
- *     key          - [OUT pre-shared key allocated and set                   *
- *                                                                            *
- * Return value:                                                              *
- *     0  - required PSK successfully found and set                           *
- *     -1 - an error occurred                                                 *
+ *     par              - [IN] not used                                       *
+ *     tls_ctx          - [IN] TLS connection context                         *
+ *     psk_identity     - [IN] PSK identity for which the PSK should be       *
+ *                             searched and set                               *
+ *     psk_identity_len - [IN] size of 'psk_identity'                         *
+ *                                                                            *
+ * Return value:                                                              *
+ *     0  - required PSK successfully found and set                           *
+ *     -1 - an error occurred                                                 *
+ *                                                                            *
+ * Comments:                                                                  *
+ *     A callback function, its arguments are defined in PolarSSL.            *
+ *     Used only in server and proxy.                                         *
+ *                                                                            *
+ ******************************************************************************/
+static int	zbx_psk_cb(void *par, mbedtls_ssl_context *tls_ctx, const unsigned char *psk_identity,
+		size_t psk_identity_len)
+{
+	const char	*__function_name = "zbx_psk_cb";
+	unsigned char	*psk;
+	size_t		psk_len = 0;
+	int		psk_bin_len;
+	unsigned char	tls_psk_identity[HOST_TLS_PSK_IDENTITY_LEN_MAX], tls_psk_hex[HOST_TLS_PSK_LEN_MAX],
+			psk_buf[HOST_TLS_PSK_LEN / 2];
+
+	if (SUCCEED == zabbix_check_log_level(LOG_LEVEL_DEBUG))
+	{
+		/* special print: psk_identity is not '\0'-terminated */
+		zabbix_log(LOG_LEVEL_DEBUG, "%s() requested PSK identity \"%.*s\"", __function_name,
+				(int)psk_identity_len, psk_identity);
+	}
+
+	/* try PSK from configuration file first (it is already in binary form) */
+
+	if (0 < my_psk_identity_len && my_psk_identity_len == psk_identity_len &&
+			0 == memcmp(my_psk_identity, psk_identity, psk_identity_len))
+	{
+		psk = (unsigned char *)my_psk;
+		psk_len = my_psk_len;
+	}
+	else	/* search the required PSK in configuration cache */
+	{
+		if (HOST_TLS_PSK_IDENTITY_LEN < psk_identity_len)
+		{
+			THIS_SHOULD_NEVER_HAPPEN;
+			return -1;
+		}
+
+		memcpy(tls_psk_identity, psk_identity, psk_identity_len);
+		tls_psk_identity[psk_identity_len] = '\0';
+
+		/* call the function DCget_psk_by_identity() by pointer */
+		if (0 < find_psk_in_cache(tls_psk_identity, tls_psk_hex, sizeof(tls_psk_hex)))
+		{
+			/* convert PSK to binary form */
+			if (0 >= (psk_bin_len = zbx_psk_hex2bin(tls_psk_hex, psk_buf, sizeof(psk_buf))))
+			{
+				/* this should have been prevented by validation in frontend or API */
+				zabbix_log(LOG_LEVEL_WARNING, "cannot convert PSK to binary form for PSK identity"
+						" \"%.*s\"", (int)psk_identity_len, psk_identity);
+				return -1;
+			}
+
+			psk = psk_buf;
+			psk_len = (size_t)psk_bin_len;
+		}
+		else
+		{
+			if (SUCCEED == zabbix_check_log_level(LOG_LEVEL_DEBUG))
+			{
+				zabbix_log(LOG_LEVEL_DEBUG, "%s() cannot find requested PSK identity \"%.*s\"",
+						__function_name, (int)psk_identity_len, psk_identity);
+			}
+		}
+	}
+
+	if (0 < psk_len)
+	{
+		int 	res;
+
+		if (0 == (res = mbedtls_ssl_set_hs_psk(tls_ctx, psk, psk_len)))
+			return 0;
+
+		zbx_tls_error_msg(res, "", &err_msg);
+		zabbix_log(LOG_LEVEL_WARNING, "cannot set PSK for PSK identity \"%.*s\": %s", (int)psk_identity_len,
+				psk_identity, err_msg);
+		zbx_free(err_msg);
+	}
+
+	return -1;
+}
+#elif defined(HAVE_GNUTLS)
+/******************************************************************************
+ *                                                                            *
+ * Function: zbx_psk_cb                                                       *
+ *                                                                            *
+ * Purpose:                                                                   *
+ *     find and set the requested pre-shared key upon GnuTLS request          *
+ *                                                                            *
+ * Parameters:                                                                *
+ *     session      - [IN] not used                                           *
+ *     psk_identity - [IN] PSK identity for which the PSK should be searched  *
+ *                         and set                                            *
+ *     key          - [OUT pre-shared key allocated and set                   *
+ *                                                                            *
+ * Return value:                                                              *
+ *     0  - required PSK successfully found and set                           *
+ *     -1 - an error occurred                                                 *
  *                                                                            *
  * Comments:                                                                  *
  *     A callback function, its arguments are defined in GnuTLS.              *
@@ -1598,6 +2007,37 @@ static void	zbx_log_ciphersuites(const char *title1, const char *title2, const i
 		zbx_free(msg);
 	}
 }
+#elif defined(HAVE_MBEDTLS21)
+/******************************************************************************
+ *                                                                            *
+ * Function: zbx_log_ciphersuites                                             *
+ *                                                                            *
+ * Purpose: write names of enabled mbed TLS ciphersuites into Zabbix log for  *
+ *          debugging                                                         *
+ *                                                                            *
+ * Parameters:                                                                *
+ *     title1     - [IN] name of the calling function                         *
+ *     title2     - [IN] name of the group of ciphersuites                    *
+ *     cipher_ids - [IN] list of ciphersuite ids, terminated by 0             *
+ *                                                                            *
+ ******************************************************************************/
+static void	zbx_log_ciphersuites(const char *title1, const char *title2, const int *cipher_ids)
+{
+	if (SUCCEED == zabbix_check_log_level(LOG_LEVEL_DEBUG))
+	{
+		char		*msg = NULL;
+		size_t		msg_alloc = 0, msg_offset = 0;
+		const int	*p;
+
+		zbx_snprintf_alloc(&msg, &msg_alloc, &msg_offset, "%s() %s ciphersuites:", title1, title2);
+
+		for (p = cipher_ids; 0 != *p; p++)
+			zbx_snprintf_alloc(&msg, &msg_alloc, &msg_offset, " %s", mbedtls_ssl_get_ciphersuite_name(*p));
+
+		zabbix_log(LOG_LEVEL_DEBUG, "%s", msg);
+		zbx_free(msg);
+	}
+}
 #elif defined(HAVE_GNUTLS)
 /******************************************************************************
  *                                                                            *
@@ -1684,7 +2124,7 @@ static void	zbx_log_ciphersuites(const char *title1, const char *title2, SSL_CTX
 }
 #endif
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS)
 /******************************************************************************
  *                                                                            *
  * Function: zbx_print_rdn_value                                              *
@@ -1921,6 +2361,117 @@ small_buf:
 
 	return FAIL;
 }
+#elif defined(HAVE_MBEDTLS21)
+/******************************************************************************
+ *                                                                            *
+ * Function: zbx_x509_dn_gets                                                 *
+ *                                                                            *
+ * Purpose:                                                                   *
+ *     Print distinguished name (i.e. issuer, subject) into buffer. Intended  *
+ *     to use as an alternative to PolarSSL mbedtls_x509_dn_gets() to meet    *
+ *     application needs.                                                     *
+ *                                                                            *
+ * Parameters:                                                                *
+ *     dn    - [IN] pointer to distinguished name                             *
+ *     buf   - [OUT] output buffer                                            *
+ *     size  - [IN] output buffer size                                        *
+ *     error - [OUT] dynamically allocated memory with error message          *
+ *                                                                            *
+ * Return value:                                                              *
+ *     SUCCEED - no errors, FAIL - an error occurred                          *
+ *                                                                            *
+ * Comments:                                                                  *
+ *     This function is derived from PolarSSL mbedtls_x509_dn_gets() and      *
+ *     heavily modified to print RDNs in reverse order, to print UTF-8        *
+ *     characters and non-printable characters in a different way than        *
+ *     original mbedtls_x509_dn_gets() does and to return error messages.     *
+ *     Multi-valued RDNs are not supported currently.                         *
+ *                                                                            *
+ ******************************************************************************/
+static int	zbx_x509_dn_gets(const mbedtls_x509_name *dn, char *buf, size_t size, char **error)
+{
+	const mbedtls_x509_name	*node, *stop_node = NULL;
+	const char	*short_name = NULL;
+	char		*p, *p_end;
+
+	/* We need to traverse a linked list of RDNs and print them out in reverse order (recommended by RFC 4514).   */
+	/* The number of RDNs in DN is expected to be small (typically 4-5, sometimes up to 8). For such a small list */
+	/* we simply traverse it multiple times for getting elements in reverse order. */
+
+	p = buf;
+	p_end = buf + size;
+
+	while (1)
+	{
+		node = dn;
+
+		while (stop_node != node->next)
+			node = node->next;
+
+		if (NULL != node->oid.p)
+		{
+			if (buf != p)				/* not the first RDN */
+			{
+				if (p_end - 1 == p)
+					goto small_buf;
+
+				p += zbx_strlcpy(p, ",", (size_t)(p_end - p));	/* separator between RDNs */
+			}
+
+			/* write attribute name */
+
+			if (0 == mbedtls_oid_get_attr_short_name(&node->oid, &short_name))
+			{
+				if (p_end - 1 == p)
+					goto small_buf;
+
+				p += zbx_strlcpy(p, short_name, (size_t)(p_end - p));
+			}
+			else	/* unknown OID name, write in numerical form */
+			{
+				int	res;
+
+				if (p_end - 1 == p)
+					goto small_buf;
+
+				if (0 < (res = mbedtls_oid_get_numeric_string(p, (size_t)(p_end - p), &node->oid)))
+					p += (size_t)res;
+				else
+					goto small_buf;
+			}
+
+			if (p_end - 1 == p)
+				goto small_buf;
+
+			p += zbx_strlcpy(p, "=", (size_t)(p_end - p));
+
+			/* write attribute value */
+
+			if (p_end - 1 == p)
+				goto small_buf;
+
+			p += zbx_print_rdn_value(node->val.p, node->val.len, (unsigned char *)p, (size_t)(p_end - p),
+					error);
+
+			if (NULL != *error)
+				break;
+		}
+
+		if (dn->next != stop_node)
+			stop_node = node;
+		else
+			break;
+	}
+
+	if (NULL == *error)
+		return SUCCEED;
+	else
+		return FAIL;
+small_buf:
+	*error = zbx_strdup(*error, "output buffer too small");
+
+	return FAIL;
+}
 #elif defined(HAVE_GNUTLS)
 /******************************************************************************
  *                                                                            *
@@ -2226,6 +2777,9 @@ static void	zbx_log_peer_cert(const char *function_name, const zbx_tls_context_t
 #if defined(HAVE_POLARSSL)
 	const x509_crt		*cert;
 	char			issuer[HOST_TLS_ISSUER_LEN_MAX], subject[HOST_TLS_SUBJECT_LEN_MAX], serial[128];
+#elif defined(HAVE_MBEDTLS21)
+	const mbedtls_x509_crt		*cert;
+	char			issuer[HOST_TLS_ISSUER_LEN_MAX], subject[HOST_TLS_SUBJECT_LEN_MAX], serial[128];
 #elif defined(HAVE_GNUTLS)
 	gnutls_x509_crt_t	cert;
 	int			res;
@@ -2259,6 +2813,28 @@ static void	zbx_log_peer_cert(const char *function_name, const zbx_tls_context_t
 		zabbix_log(LOG_LEVEL_DEBUG, "%s() peer certificate issuer:\"%s\" subject:\"%s\" serial:\"%s\"",
 				function_name, issuer, subject, serial);
 	}
+#elif defined(HAVE_MBEDTLS21)
+	if (NULL == (cert = mbedtls_ssl_get_peer_cert(tls_ctx->ctx)))
+	{
+		zabbix_log(LOG_LEVEL_DEBUG, "%s() cannot obtain peer certificate", function_name);
+	}
+	else if (SUCCEED != zbx_x509_dn_gets(&cert->issuer, issuer, sizeof(issuer), &error))
+	{
+		zabbix_log(LOG_LEVEL_DEBUG, "%s() cannot obtain peer certificate issuer: %s", function_name, error);
+	}
+	else if (SUCCEED != zbx_x509_dn_gets(&cert->subject, subject, sizeof(subject), &error))
+	{
+		zabbix_log(LOG_LEVEL_DEBUG, "%s() cannot obtain peer certificate subject: %s", function_name, error);
+	}
+	else if (0 > mbedtls_x509_serial_gets(serial, sizeof(serial), &cert->serial))
+	{
+		zabbix_log(LOG_LEVEL_DEBUG, "%s() cannot obtain peer certificate serial", function_name);
+	}
+	else
+	{
+		zabbix_log(LOG_LEVEL_DEBUG, "%s() peer certificate issuer:\"%s\" subject:\"%s\" serial:\"%s\"",
+				function_name, issuer, subject, serial);
+	}
 #elif defined(HAVE_GNUTLS)
 	if (NULL == (cert = zbx_get_peer_cert(tls_ctx->ctx, &error)))
 	{
@@ -2373,6 +2949,8 @@ static int	zbx_verify_issuer_subject(const zbx_tls_context_t *tls_ctx, const cha
 	size_t			error_alloc = 0, error_offset = 0;
 #if defined(HAVE_POLARSSL)
 	const x509_crt		*cert;
+#elif defined(HAVE_MBEDTLS21)
+	const mbedtls_x509_crt		*cert;
 #elif defined(HAVE_GNUTLS)
 	gnutls_x509_crt_t	cert;
 	gnutls_x509_dn_t	dn;
@@ -2401,6 +2979,24 @@ static int	zbx_verify_issuer_subject(const zbx_tls_context_t *tls_ctx, const cha
 		if (SUCCEED != zbx_x509_dn_gets(&cert->subject, tls_subject, sizeof(tls_subject), error))
 			return FAIL;
 	}
+#elif defined(HAVE_MBEDTLS21)
+	if (NULL == (cert = mbedtls_ssl_get_peer_cert(tls_ctx->ctx)))
+	{
+		*error = zbx_strdup(*error, "cannot obtain peer certificate");
+		return FAIL;
+	}
+
+	if (NULL != issuer && '\0' != *issuer)
+	{
+		if (SUCCEED != zbx_x509_dn_gets(&cert->issuer, tls_issuer, sizeof(tls_issuer), error))
+			return FAIL;
+	}
+
+	if (NULL != subject && '\0' != *subject)
+	{
+		if (SUCCEED != zbx_x509_dn_gets(&cert->subject, tls_subject, sizeof(tls_subject), error))
+			return FAIL;
+	}
 #elif defined(HAVE_GNUTLS)
 	if (NULL == (cert = zbx_get_peer_cert(tls_ctx->ctx, error)))
 		return FAIL;
@@ -2547,6 +3143,8 @@ static void	zbx_tls_library_init(void)
 {
 #if defined(HAVE_POLARSSL)
 	zabbix_log(LOG_LEVEL_DEBUG, "mbed TLS library (version %s)", POLARSSL_VERSION_STRING_FULL);
+#elif defined(HAVE_MBEDTLS21)
+	zabbix_log(LOG_LEVEL_DEBUG, "mbed TLS library (version %s)", MBEDTLS_VERSION_STRING_FULL);
 #elif defined(HAVE_GNUTLS)
 	if (GNUTLS_E_SUCCESS != gnutls_global_init())
 	{
@@ -2812,6 +3410,203 @@ void	zbx_tls_init_child(void)
 #endif
 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
 }
+#elif defined(HAVE_MBEDTLS21)
+void	zbx_tls_init_child(void)
+{
+	const char	*__function_name = "zbx_tls_init_child";
+	int		res;
+	unsigned char	pers[64];	/* personalization string obtained from SHA-512 in SHA-384 mode */
+#ifndef _WINDOWS
+	sigset_t	mask, orig_mask;
+#endif
+	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
+
+#ifndef _WINDOWS
+	/* Invalid TLS parameters will cause exit. Once one process exits the parent process will send SIGTERM to */
+	/* child processes which may be on their way to exit on their own - do not interrupt them, block signal */
+	/* SIGTERM and unblock it when TLS parameters are good and libraries are initialized. */
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGTERM);
+	sigprocmask(SIG_BLOCK, &mask, &orig_mask);
+
+	zbx_tls_library_init();		/* on Unix initialize crypto libraries in child processes */
+#endif
+	/* 'TLSCAFile' parameter (in zabbix_server.conf, zabbix_proxy.conf, zabbix_agentd.conf). */
+	if (NULL != CONFIG_TLS_CA_FILE)
+	{
+		ca_cert = zbx_malloc(ca_cert, sizeof(mbedtls_x509_crt));
+		mbedtls_x509_crt_init(ca_cert);
+
+		if (0 != (res = mbedtls_x509_crt_parse_file(ca_cert, CONFIG_TLS_CA_FILE)))
+		{
+			if (0 > res)
+			{
+				zbx_tls_error_msg(res, "", &err_msg);
+				zabbix_log(LOG_LEVEL_CRIT, "cannot parse CA certificate(s) in file \"%s\": %s",
+						CONFIG_TLS_CA_FILE, err_msg);
+				zbx_free(err_msg);
+			}
+			else
+			{
+				zabbix_log(LOG_LEVEL_CRIT, "cannot parse %d CA certificate(s) in file \"%s\"", res,
+						CONFIG_TLS_CA_FILE);
+			}
+
+			zbx_tls_free();
+			exit(EXIT_FAILURE);
+		}
+
+		zabbix_log(LOG_LEVEL_DEBUG, "%s() loaded CA certificate(s) from file \"%s\"", __function_name,
+				CONFIG_TLS_CA_FILE);
+	}
+
+	/* 'TLSCRLFile' parameter (in zabbix_server.conf, zabbix_proxy.conf, zabbix_agentd.conf). */
+	/* Load CRL (certificate revocation list) file. */
+	if (NULL != CONFIG_TLS_CRL_FILE)
+	{
+		crl = zbx_malloc(crl, sizeof(mbedtls_x509_crl));
+		mbedtls_x509_crl_init(crl);
+
+		if (0 != (res = mbedtls_x509_crl_parse_file(crl, CONFIG_TLS_CRL_FILE)))
+		{
+			zbx_tls_error_msg(res, "", &err_msg);
+			zabbix_log(LOG_LEVEL_CRIT, "cannot parse CRL file \"%s\": %s", CONFIG_TLS_CRL_FILE, err_msg);
+			zbx_free(err_msg);
+
+			zbx_tls_free();
+			exit(EXIT_FAILURE);
+		}
+
+		zabbix_log(LOG_LEVEL_DEBUG, "%s() loaded CRL(s) from file \"%s\"", __function_name,
+				CONFIG_TLS_CRL_FILE);
+	}
+
+	/* 'TLSCertFile' parameter (in zabbix_server.conf, zabbix_proxy.conf, zabbix_agentd.conf). */
+	/* Load certificate. */
+	if (NULL != CONFIG_TLS_CERT_FILE)
+	{
+		my_cert = zbx_malloc(my_cert, sizeof(mbedtls_x509_crt));
+		mbedtls_x509_crt_init(my_cert);
+
+		if (0 != (res = mbedtls_x509_crt_parse_file(my_cert, CONFIG_TLS_CERT_FILE)))
+		{
+			if (0 > res)
+			{
+				zbx_tls_error_msg(res, "", &err_msg);
+				zabbix_log(LOG_LEVEL_CRIT, "cannot parse certificate(s) in file \"%s\": %s",
+						CONFIG_TLS_CERT_FILE, err_msg);
+				zbx_free(err_msg);
+			}
+			else
+			{
+				zabbix_log(LOG_LEVEL_CRIT, "cannot parse %d certificate(s) in file \"%s\"", res,
+						CONFIG_TLS_CERT_FILE);
+			}
+
+			zbx_tls_free();
+			exit(EXIT_FAILURE);
+		}
+
+		zabbix_log(LOG_LEVEL_DEBUG, "%s() loaded certificate from file \"%s\"", __function_name,
+				CONFIG_TLS_CERT_FILE);
+	}
+
+	/* 'TLSKeyFile' parameter (in zabbix_server.conf, zabbix_proxy.conf, zabbix_agentd.conf). */
+	/* Load private key. */
+	if (NULL != CONFIG_TLS_KEY_FILE)
+	{
+		my_priv_key = zbx_malloc(my_priv_key, sizeof(mbedtls_pk_context));
+		mbedtls_pk_init(my_priv_key);
+
+		/* The 3rd argument of mbedtls_pk_parse_keyfile() is password for decrypting the private key. */
+		/* Currently the password is not used, it is empty. */
+		if (0 != (res = mbedtls_pk_parse_keyfile(my_priv_key, CONFIG_TLS_KEY_FILE, "")))
+		{
+			zbx_tls_error_msg(res, "", &err_msg);
+			zabbix_log(LOG_LEVEL_CRIT, "cannot parse the private key in file \"%s\": %s",
+					CONFIG_TLS_KEY_FILE, err_msg);
+			zbx_free(err_msg);
+			zbx_tls_free();
+			exit(EXIT_FAILURE);
+		}
+
+		zabbix_log(LOG_LEVEL_DEBUG, "%s() loaded " ZBX_FS_SIZE_T "-bit %s private key from file \"%s\"",
+				__function_name, (zbx_fs_size_t)mbedtls_pk_get_bitlen(my_priv_key), mbedtls_pk_get_name(my_priv_key),
+				CONFIG_TLS_KEY_FILE);
+	}
+
+	/* 'TLSPSKFile' parameter (in zabbix_proxy.conf, zabbix_agentd.conf). */
+	/* Load pre-shared key. */
+	if (NULL != CONFIG_TLS_PSK_FILE)
+	{
+		zbx_read_psk_file();
+		zabbix_log(LOG_LEVEL_DEBUG, "%s() loaded PSK from file \"%s\"", __function_name, CONFIG_TLS_PSK_FILE);
+	}
+
+	/* 'TLSPSKIdentity' parameter (in zabbix_proxy.conf, zabbix_agentd.conf). */
+	/* Configure identity to be used with the pre-shared key. */
+	if (NULL != CONFIG_TLS_PSK_IDENTITY)
+	{
+		my_psk_identity = CONFIG_TLS_PSK_IDENTITY;
+		my_psk_identity_len = strlen(my_psk_identity);
+
+		zbx_check_psk_identity_len(my_psk_identity_len);
+
+		zabbix_log(LOG_LEVEL_DEBUG, "%s() loaded PSK identity \"%s\"", __function_name,
+				CONFIG_TLS_PSK_IDENTITY);
+	}
+
+	/* Certificate always comes from configuration file. Set up ciphersuites. */
+	if (NULL != my_cert)
+	{
+		zbx_ciphersuites(ZBX_TLS_CIPHERSUITE_CERT, &ciphersuites_cert);
+		zbx_log_ciphersuites(__function_name, "certificate", ciphersuites_cert);
+	}
+
+	/* PSK can come from configuration file (in proxy, agentd) and later from database (in server, proxy). */
+	/* Configure ciphersuites just in case they will be used. */
+	if (NULL != my_psk || 0 != (program_type & (ZBX_PROGRAM_TYPE_SERVER | ZBX_PROGRAM_TYPE_PROXY)))
+	{
+		zbx_ciphersuites(ZBX_TLS_CIPHERSUITE_PSK, &ciphersuites_psk);
+		zbx_log_ciphersuites(__function_name, "PSK", ciphersuites_psk);
+	}
+
+	/* Sometimes we need to be ready for both certificate and PSK whichever comes in. Set up a combined list of */
+	/* ciphersuites. */
+	if (NULL != my_cert && (NULL != my_psk ||
+			0 != (program_type & (ZBX_PROGRAM_TYPE_SERVER | ZBX_PROGRAM_TYPE_PROXY))))
+	{
+		zbx_ciphersuites(ZBX_TLS_CIPHERSUITE_ALL, &ciphersuites_all);
+		zbx_log_ciphersuites(__function_name, "certificate and PSK", ciphersuites_all);
+	}
+
+	entropy = zbx_malloc(entropy, sizeof(mbedtls_entropy_context));
+	mbedtls_entropy_init(entropy);
+
+	zbx_make_personalization_string(pers);
+
+	ctr_drbg = zbx_malloc(ctr_drbg, sizeof(mbedtls_ctr_drbg_context));
+	mbedtls_ctr_drbg_init(ctr_drbg);
+
+	if (0 != (res = mbedtls_ctr_drbg_seed(ctr_drbg, mbedtls_entropy_func, entropy, pers, 48)))
+		/* PolarSSL mbedtls_sha512_finish() in SHA-384 mode returns an array "unsigned char output[64]" where result */
+		/* resides in the first 48 bytes and the last 16 bytes are not used */
+	{
+		zbx_guaranteed_memset(pers, 0, sizeof(pers));
+		zbx_tls_error_msg(res, "", &err_msg);
+		zabbix_log(LOG_LEVEL_CRIT, "cannot initialize random number generator: %s", err_msg);
+		zbx_free(err_msg);
+		zbx_tls_free();
+		exit(EXIT_FAILURE);
+	}
+
+	zbx_guaranteed_memset(pers, 0, sizeof(pers));
+
+#ifndef _WINDOWS
+	sigprocmask(SIG_SETMASK, &orig_mask, NULL);
+#endif
+	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
+}
 #elif defined(HAVE_GNUTLS)
 void	zbx_tls_init_child(void)
 {
@@ -3516,6 +4311,53 @@ void	zbx_tls_free(void)
 	zbx_free(ciphersuites_psk);
 	zbx_free(ciphersuites_cert);
 	zbx_free(ciphersuites_all);
+#elif defined(HAVE_MBEDTLS21)
+	if (NULL != ctr_drbg)
+	{
+		mbedtls_ctr_drbg_free(ctr_drbg);
+		zbx_free(ctr_drbg);
+	}
+
+	if (NULL != entropy)
+	{
+		mbedtls_entropy_free(entropy);
+		zbx_free(entropy);
+	}
+
+	if (NULL != my_psk)
+	{
+		zbx_guaranteed_memset(my_psk, 0, my_psk_len);
+		my_psk_len = 0;
+		zbx_free(my_psk);
+	}
+
+	if (NULL != my_priv_key)
+	{
+		mbedtls_pk_free(my_priv_key);
+		zbx_free(my_priv_key);
+	}
+
+	if (NULL != my_cert)
+	{
+		mbedtls_x509_crt_free(my_cert);
+		zbx_free(my_cert);
+	}
+
+	if (NULL != crl)
+	{
+		mbedtls_x509_crl_free(crl);
+		zbx_free(crl);
+	}
+
+	if (NULL != ca_cert)
+	{
+		mbedtls_x509_crt_free(ca_cert);
+		zbx_free(ca_cert);
+	}
+
+	zbx_free(ciphersuites_psk);
+	zbx_free(ciphersuites_cert);
+	zbx_free(ciphersuites_all);
 #elif defined(HAVE_GNUTLS)
 	if (NULL != my_cert_creds)
 	{
@@ -3690,27 +4532,245 @@ int	zbx_tls_connect(zbx_socket_t *s, unsigned int tls_connect, char *tls_arg1, c
 		ssl_set_ciphersuites(s->tls_ctx->ctx, ciphersuites_cert);
 
 		/* set CA certificate and certificate revocation lists */
-		ssl_set_ca_chain(s->tls_ctx->ctx, ca_cert, crl, NULL);
+		ssl_set_ca_chain(s->tls_ctx->ctx, ca_cert, crl, NULL);
+
+		if (0 != (res = ssl_set_own_cert(s->tls_ctx->ctx, my_cert, my_priv_key)))
+		{
+			zbx_tls_error_msg(res, "ssl_set_own_cert(): ", error);
+			goto out;
+		}
+	}
+	else	/* use a pre-shared key */
+	{
+		ssl_set_ciphersuites(s->tls_ctx->ctx, ciphersuites_psk);
+
+		if (NULL == tls_arg2)	/* PSK is not set from DB */
+		{
+			/* set up the PSK from a configuration file (always in agentd and a case in active proxy */
+			/* when it connects to server) */
+
+			if (0 != (res = ssl_set_psk(s->tls_ctx->ctx, (const unsigned char *)my_psk, my_psk_len,
+					(const unsigned char *)my_psk_identity, my_psk_identity_len)))
+			{
+				zbx_tls_error_msg(res, "ssl_set_psk(): ", error);
+				goto out;
+			}
+		}
+		else
+		{
+			/* PSK comes from a database (case for a server/proxy when it connects to an agent for */
+			/* passive checks, for a server when it connects to a passive proxy) */
+
+			int	psk_len;
+			char	psk_buf[HOST_TLS_PSK_LEN / 2];
+
+			if (0 >= (psk_len = zbx_psk_hex2bin((unsigned char *)tls_arg2, (unsigned char *)psk_buf,
+					sizeof(psk_buf))))
+			{
+				*error = zbx_strdup(*error, "invalid PSK");
+				goto out;
+			}
+
+			if (0 != (res = ssl_set_psk(s->tls_ctx->ctx, (const unsigned char *)psk_buf, (size_t)psk_len,
+					(const unsigned char *)tls_arg1, strlen(tls_arg1))))
+			{
+				zbx_tls_error_msg(res, "ssl_set_psk(): ", error);
+				goto out;
+			}
+		}
+	}
+
+#if defined(_WINDOWS)
+	zbx_alarm_flag_clear();
+	sec = zbx_time();
+#endif
+	while (0 != (res = ssl_handshake(s->tls_ctx->ctx)))
+	{
+#if defined(_WINDOWS)
+		if (s->timeout < zbx_time() - sec)
+			zbx_alarm_flag_set();
+#endif
+		if (SUCCEED == zbx_alarm_timed_out())
+		{
+			*error = zbx_strdup(*error, "ssl_handshake() timed out");
+			goto out;
+		}
+
+		if (POLARSSL_ERR_NET_WANT_READ != res && POLARSSL_ERR_NET_WANT_WRITE != res)
+		{
+			if (POLARSSL_ERR_X509_CERT_VERIFY_FAILED == res)
+			{
+				/* Standard PolarSSL error message might not be very informative in this case. For */
+				/* example, if certificate validity starts in future, PolarSSL 1.3.9 would produce a */
+				/* message "X509 - Certificate verification failed, e.g. CRL, CA or signature check */
+				/* failed" which does not give a precise reason. Here we try to get more detailed */
+				/* reason why peer certificate was rejected by using some knowledge about PolarSSL */
+				/* internals. */
+				zbx_tls_cert_error_msg((unsigned int)s->tls_ctx->ctx->session_negotiate->verify_result,
+						error);
+				zbx_tls_close(s);
+				goto out1;
+			}
+
+			zbx_tls_error_msg(res, "ssl_handshake(): ", error);
+			goto out;
+		}
+	}
+
+	if (ZBX_TCP_SEC_TLS_CERT == tls_connect)
+	{
+		/* log peer certificate information for debugging */
+		zbx_log_peer_cert(__function_name, s->tls_ctx);
+
+		/* basic verification of peer certificate was done during handshake */
+
+		/* if required verify peer certificate Issuer and Subject */
+		if (SUCCEED != zbx_verify_issuer_subject(s->tls_ctx, tls_arg1, tls_arg2, error))
+		{
+			zbx_tls_close(s);
+			goto out1;
+		}
+	}
+	else	/* pre-shared key */
+	{
+		if (SUCCEED == zabbix_check_log_level(LOG_LEVEL_DEBUG))
+		{
+			/* special print: s->tls_ctx->ctx->psk_identity is not '\0'-terminated */
+			zabbix_log(LOG_LEVEL_DEBUG, "%s() PSK identity: \"%.*s\"", __function_name,
+					(int)s->tls_ctx->ctx->psk_identity_len, s->tls_ctx->ctx->psk_identity);
+		}
+	}
+
+	s->connection_type = tls_connect;
+
+	if (SUCCEED == zabbix_check_log_level(LOG_LEVEL_DEBUG))
+	{
+		zabbix_log(LOG_LEVEL_DEBUG, "End of %s():SUCCEED (established %s %s)", __function_name,
+				ssl_get_version(s->tls_ctx->ctx), ssl_get_ciphersuite(s->tls_ctx->ctx));
+	}
+
+	return SUCCEED;
+
+out:	/* an error occurred */
+	ssl_free(s->tls_ctx->ctx);
+	zbx_free(s->tls_ctx->ctx);
+	zbx_free(s->tls_ctx);
+out1:
+	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s error:'%s'", __function_name, zbx_result_string(ret),
+			ZBX_NULL2EMPTY_STR(*error));
+	return ret;
+}
+#elif defined(HAVE_MBEDTLS21)
+int	zbx_tls_connect(zbx_socket_t *s, unsigned int tls_connect, char *tls_arg1, char *tls_arg2, char **error)
+{
+	const char	*__function_name = "zbx_tls_connect";
+	int		ret = FAIL, res;
+#if defined(_WINDOWS)
+	double		sec;
+#endif
+	if (ZBX_TCP_SEC_TLS_CERT == tls_connect)
+	{
+		zabbix_log(LOG_LEVEL_DEBUG, "In %s(): issuer:\"%s\" subject:\"%s\"", __function_name,
+				ZBX_NULL2EMPTY_STR(tls_arg1), ZBX_NULL2EMPTY_STR(tls_arg2));
+
+		if (NULL == ciphersuites_cert)
+		{
+			*error = zbx_strdup(*error, "cannot connect with TLS and certificate: no valid certificate"
+					" loaded");
+			goto out1;
+		}
+	}
+	else if (ZBX_TCP_SEC_TLS_PSK == tls_connect)
+	{
+		zabbix_log(LOG_LEVEL_DEBUG, "In %s(): psk_identity:\"%s\"", __function_name,
+				ZBX_NULL2EMPTY_STR(tls_arg1));
+
+		if (NULL == ciphersuites_psk)
+		{
+			*error = zbx_strdup(*error, "cannot connect with TLS and PSK: no valid PSK loaded");
+			goto out1;
+		}
+	}
+	else
+	{
+		*error = zbx_strdup(*error, "invalid connection parameters");
+		THIS_SHOULD_NEVER_HAPPEN;
+		goto out1;
+	}
+
+	/* set up TLS context */
+
+	s->tls_ctx = zbx_malloc(s->tls_ctx, sizeof(zbx_tls_context_t));
+	s->tls_ctx->conf = zbx_malloc(NULL, sizeof(mbedtls_ssl_config));
+	mbedtls_ssl_config_init(s->tls_ctx->conf);
+	s->tls_ctx->ctx = zbx_malloc(NULL, sizeof(mbedtls_ssl_context));
+	mbedtls_ssl_init(s->tls_ctx->ctx);
+
+	if (0 != (res = mbedtls_ssl_config_defaults(s->tls_ctx->conf,
+			MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)))
+	{
+		zbx_tls_error_msg(res, "mbedtls_ssl_config_defaults(): ", error);
+		goto out_pre_setup;
+	}
+
+	if (0 != (res = mbedtls_ssl_setup(s->tls_ctx->ctx, s->tls_ctx->conf)))
+	{
+		zbx_tls_error_msg(res, "mbedtls_ssl_setup(): ", error);
+		goto out;
+	}
+
+	/* Set RNG callback where to get random numbers from */
+	mbedtls_ssl_conf_rng(s->tls_ctx->conf, mbedtls_ctr_drbg_random, ctr_drbg);
+
+	/* disable using of session tickets (by default it is enabled on client) */
+	mbedtls_ssl_conf_session_tickets(s->tls_ctx->conf, MBEDTLS_SSL_SESSION_TICKETS_DISABLED);
+
+	if (SUCCEED == zabbix_check_log_level(LOG_LEVEL_TRACE))
+	{
+		/* Set our own debug callback function. The 3rd parameter of mbedtls_ssl_conf_dbg() we set to NULL. It will be */
+		/* passed as the 1st parameter to our callback function and will be ignored there. */
+		mbedtls_ssl_conf_dbg(s->tls_ctx->conf, polarssl_debug_cb, NULL);
+
+		/* For Zabbix LOG_LEVEL_TRACE, PolarSSL debug level 3 seems the best. Recompile with 4 (apparently */
+		/* the highest PolarSSL debug level) to dump also network raw bytes. */
+		mbedtls_debug_set_threshold(3);
+	}
+
+	/* Set callback functions for receiving and sending data via socket. */
+	/* Functions provided by PolarSSL work well so far, no need to invent our own. */
+	mbedtls_ssl_set_bio(s->tls_ctx->ctx, &s->socket, mbedtls_net_send, mbedtls_net_recv, NULL);
+
+	/* set protocol version to TLS 1.2 */
+	mbedtls_ssl_conf_min_version(s->tls_ctx->conf, ZBX_TLS_MIN_MAJOR_VER, ZBX_TLS_MIN_MINOR_VER);
+	mbedtls_ssl_conf_max_version(s->tls_ctx->conf, ZBX_TLS_MAX_MAJOR_VER, ZBX_TLS_MAX_MINOR_VER);
+
+	if (ZBX_TCP_SEC_TLS_CERT == tls_connect)	/* use certificates */
+	{
+		mbedtls_ssl_conf_authmode(s->tls_ctx->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
+		mbedtls_ssl_conf_ciphersuites(s->tls_ctx->conf, ciphersuites_cert);
+
+		/* set CA certificate and certificate revocation lists */
+		mbedtls_ssl_conf_ca_chain(s->tls_ctx->conf, ca_cert, crl);
 
-		if (0 != (res = ssl_set_own_cert(s->tls_ctx->ctx, my_cert, my_priv_key)))
+		if (0 != (res = mbedtls_ssl_conf_own_cert(s->tls_ctx->conf, my_cert, my_priv_key)))
 		{
-			zbx_tls_error_msg(res, "ssl_set_own_cert(): ", error);
+			zbx_tls_error_msg(res, "mbedtls_ssl_conf_own_cert(): ", error);
 			goto out;
 		}
 	}
 	else	/* use a pre-shared key */
 	{
-		ssl_set_ciphersuites(s->tls_ctx->ctx, ciphersuites_psk);
+		mbedtls_ssl_conf_ciphersuites(s->tls_ctx->conf, ciphersuites_psk);
 
 		if (NULL == tls_arg2)	/* PSK is not set from DB */
 		{
 			/* set up the PSK from a configuration file (always in agentd and a case in active proxy */
 			/* when it connects to server) */
 
-			if (0 != (res = ssl_set_psk(s->tls_ctx->ctx, (const unsigned char *)my_psk, my_psk_len,
+			if (0 != (res = mbedtls_ssl_conf_psk(s->tls_ctx->conf, (const unsigned char *)my_psk, my_psk_len,
 					(const unsigned char *)my_psk_identity, my_psk_identity_len)))
 			{
-				zbx_tls_error_msg(res, "ssl_set_psk(): ", error);
+				zbx_tls_error_msg(res, "mbedtls_ssl_conf_psk(): ", error);
 				goto out;
 			}
 		}
@@ -3729,10 +4789,10 @@ int	zbx_tls_connect(zbx_socket_t *s, unsigned int tls_connect, char *tls_arg1, c
 				goto out;
 			}
 
-			if (0 != (res = ssl_set_psk(s->tls_ctx->ctx, (const unsigned char *)psk_buf, (size_t)psk_len,
+			if (0 != (res = mbedtls_ssl_conf_psk(s->tls_ctx->conf, (const unsigned char *)psk_buf, (size_t)psk_len,
 					(const unsigned char *)tls_arg1, strlen(tls_arg1))))
 			{
-				zbx_tls_error_msg(res, "ssl_set_psk(): ", error);
+				zbx_tls_error_msg(res, "mbedtls_ssl_conf_psk(): ", error);
 				goto out;
 			}
 		}
@@ -3742,7 +4802,7 @@ int	zbx_tls_connect(zbx_socket_t *s, unsigned int tls_connect, char *tls_arg1, c
 	zbx_alarm_flag_clear();
 	sec = zbx_time();
 #endif
-	while (0 != (res = ssl_handshake(s->tls_ctx->ctx)))
+	while (0 != (res = mbedtls_ssl_handshake(s->tls_ctx->ctx)))
 	{
 #if defined(_WINDOWS)
 		if (s->timeout < zbx_time() - sec)
@@ -3750,13 +4810,13 @@ int	zbx_tls_connect(zbx_socket_t *s, unsigned int tls_connect, char *tls_arg1, c
 #endif
 		if (SUCCEED == zbx_alarm_timed_out())
 		{
-			*error = zbx_strdup(*error, "ssl_handshake() timed out");
+			*error = zbx_strdup(*error, "mbedtls_ssl_handshake() timed out");
 			goto out;
 		}
 
-		if (POLARSSL_ERR_NET_WANT_READ != res && POLARSSL_ERR_NET_WANT_WRITE != res)
+		if (MBEDTLS_ERR_SSL_WANT_READ != res && MBEDTLS_ERR_SSL_WANT_WRITE != res)
 		{
-			if (POLARSSL_ERR_X509_CERT_VERIFY_FAILED == res)
+			if (MBEDTLS_ERR_X509_CERT_VERIFY_FAILED == res)
 			{
 				/* Standard PolarSSL error message might not be very informative in this case. For */
 				/* example, if certificate validity starts in future, PolarSSL 1.3.9 would produce a */
@@ -3770,7 +4830,7 @@ int	zbx_tls_connect(zbx_socket_t *s, unsigned int tls_connect, char *tls_arg1, c
 				goto out1;
 			}
 
-			zbx_tls_error_msg(res, "ssl_handshake(): ", error);
+			zbx_tls_error_msg(res, "mbedtls_ssl_handshake(): ", error);
 			goto out;
 		}
 	}
@@ -3795,7 +4855,7 @@ int	zbx_tls_connect(zbx_socket_t *s, unsigned int tls_connect, char *tls_arg1, c
 		{
 			/* special print: s->tls_ctx->ctx->psk_identity is not '\0'-terminated */
 			zabbix_log(LOG_LEVEL_DEBUG, "%s() PSK identity: \"%.*s\"", __function_name,
-					(int)s->tls_ctx->ctx->psk_identity_len, s->tls_ctx->ctx->psk_identity);
+					(int)s->tls_ctx->conf->psk_identity_len, s->tls_ctx->conf->psk_identity);
 		}
 	}
 
@@ -3804,14 +4864,17 @@ int	zbx_tls_connect(zbx_socket_t *s, unsigned int tls_connect, char *tls_arg1, c
 	if (SUCCEED == zabbix_check_log_level(LOG_LEVEL_DEBUG))
 	{
 		zabbix_log(LOG_LEVEL_DEBUG, "End of %s():SUCCEED (established %s %s)", __function_name,
-				ssl_get_version(s->tls_ctx->ctx), ssl_get_ciphersuite(s->tls_ctx->ctx));
+				mbedtls_ssl_get_version(s->tls_ctx->ctx), mbedtls_ssl_get_ciphersuite(s->tls_ctx->ctx));
 	}
 
 	return SUCCEED;
 
 out:	/* an error occurred */
-	ssl_free(s->tls_ctx->ctx);
+	mbedtls_ssl_free(s->tls_ctx->ctx);
 	zbx_free(s->tls_ctx->ctx);
+out_pre_setup:
+	mbedtls_ssl_config_free(s->tls_ctx->conf);
+	zbx_free(s->tls_ctx->conf);
 	zbx_free(s->tls_ctx);
 out1:
 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s error:'%s'", __function_name, zbx_result_string(ret),
@@ -4543,6 +5606,211 @@ out1:
 			ZBX_NULL2EMPTY_STR(*error));
 	return ret;
 }
+#elif defined(HAVE_MBEDTLS21)
+int	zbx_tls_accept(zbx_socket_t *s, unsigned int tls_accept, char **error)
+{
+	const char		*__function_name = "zbx_tls_accept";
+	int			ret = FAIL, res;
+	const mbedtls_ssl_ciphersuite_t	*info;
+#if defined(_WINDOWS)
+	double			sec;
+#endif
+	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
+
+	/* set up TLS context */
+
+	s->tls_ctx = zbx_malloc(s->tls_ctx, sizeof(zbx_tls_context_t));
+	s->tls_ctx->conf = zbx_malloc(NULL, sizeof(mbedtls_ssl_config));
+	mbedtls_ssl_config_init(s->tls_ctx->conf);
+	s->tls_ctx->ctx = zbx_malloc(NULL, sizeof(mbedtls_ssl_context));
+	mbedtls_ssl_init(s->tls_ctx->ctx);
+
+	if (0 != (res = mbedtls_ssl_config_defaults(s->tls_ctx->conf,
+			MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)))
+	{
+		zbx_tls_error_msg(res, "mbedtls_ssl_config_defaults(): ", error);
+		goto out_pre_setup;
+	}
+
+	if (0 != (res = mbedtls_ssl_setup(s->tls_ctx->ctx, s->tls_ctx->conf)))
+	{
+		zbx_tls_error_msg(res, "mbedtls_ssl_setup(): ", error);
+		goto out;
+	}
+
+	/* Set RNG callback where to get random numbers from */
+	mbedtls_ssl_conf_rng(s->tls_ctx->conf, mbedtls_ctr_drbg_random, ctr_drbg);
+
+	/* explicitly disable using of session tickets (although by default it is disabled on server) */
+	mbedtls_ssl_conf_session_tickets(s->tls_ctx->conf, MBEDTLS_SSL_SESSION_TICKETS_DISABLED);
+
+	if (SUCCEED == zabbix_check_log_level(LOG_LEVEL_TRACE))
+	{
+		/* Set our own debug callback function. The 3rd parameter of mbedtls_ssl_conf_dbg() we set to NULL. It will be */
+		/* passed as the 1st parameter to our callback function and will be ignored there. */
+		mbedtls_ssl_conf_dbg(s->tls_ctx->conf, polarssl_debug_cb, NULL);
+
+		/* For Zabbix LOG_LEVEL_TRACE, PolarSSL debug level 3 seems the best. Recompile with 4 (apparently */
+		/* the highest PolarSSL debug level) to dump also network raw bytes. */
+		mbedtls_debug_set_threshold(3);
+	}
+
+	/* Set callback functions for receiving and sending data via socket. */
+	/* Functions provided by PolarSSL work well so far, no need to invent our own. */
+	mbedtls_ssl_set_bio(s->tls_ctx->ctx, &s->socket, mbedtls_net_send, mbedtls_net_recv, NULL);
+
+	/* set protocol version to TLS 1.2 */
+	mbedtls_ssl_conf_min_version(s->tls_ctx->conf, ZBX_TLS_MIN_MAJOR_VER, ZBX_TLS_MIN_MINOR_VER);
+	mbedtls_ssl_conf_max_version(s->tls_ctx->conf, ZBX_TLS_MAX_MAJOR_VER, ZBX_TLS_MAX_MINOR_VER);
+
+	/* prepare to accept with certificate */
+
+	if (0 != (tls_accept & ZBX_TCP_SEC_TLS_CERT))
+	{
+		mbedtls_ssl_conf_authmode(s->tls_ctx->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
+
+		/* set CA certificate and certificate revocation lists */
+		if (NULL != ca_cert)
+			mbedtls_ssl_conf_ca_chain(s->tls_ctx->conf, ca_cert, crl);
+
+		if (NULL != my_cert && 0 != (res = mbedtls_ssl_conf_own_cert(s->tls_ctx->conf, my_cert, my_priv_key)))
+		{
+			zbx_tls_error_msg(res, "mbedtls_ssl_conf_own_cert(): ", error);
+			goto out;
+		}
+	}
+
+	/* prepare to accept with pre-shared key */
+
+	if (0 != (tls_accept & ZBX_TCP_SEC_TLS_PSK))
+	{
+		/* for agentd the only possibility is a PSK from configuration file */
+		if (0 != (program_type & ZBX_PROGRAM_TYPE_AGENTD) &&
+				0 != (res = mbedtls_ssl_conf_psk(s->tls_ctx->conf, (const unsigned char *)my_psk, my_psk_len,
+				(const unsigned char *)my_psk_identity, my_psk_identity_len)))
+		{
+			zbx_tls_error_msg(res, "mbedtls_ssl_conf_psk(): ", error);
+			goto out;
+		}
+		else if (0 != (program_type & (ZBX_PROGRAM_TYPE_PROXY | ZBX_PROGRAM_TYPE_SERVER)))
+		{
+			/* For server or proxy a PSK can come from configuration file or database. */
+			/* Set up a callback function for finding the requested PSK. */
+			mbedtls_ssl_conf_psk_cb(s->tls_ctx->conf, zbx_psk_cb, NULL);
+		}
+	}
+
+	/* set up ciphersuites */
+
+	if ((ZBX_TCP_SEC_TLS_CERT | ZBX_TCP_SEC_TLS_PSK) == (tls_accept & (ZBX_TCP_SEC_TLS_CERT | ZBX_TCP_SEC_TLS_PSK)))
+	{
+		/* common case in trapper - be ready for all types of incoming connections */
+		if (NULL != my_cert)
+		{
+			/* it can also be a case in agentd listener - when both certificate and PSK is allowed, e.g. */
+			/* for switching of TLS connections from PSK to using a certificate */
+			mbedtls_ssl_conf_ciphersuites(s->tls_ctx->conf, ciphersuites_all);
+		}
+		else
+		{
+			/* assume PSK, although it is not yet known will there be the right PSK available */
+			mbedtls_ssl_conf_ciphersuites(s->tls_ctx->conf, ciphersuites_psk);
+		}
+	}
+	else if (0 != (tls_accept & ZBX_TCP_SEC_TLS_CERT) && NULL != my_cert)
+		mbedtls_ssl_conf_ciphersuites(s->tls_ctx->conf, ciphersuites_cert);
+	else if (0 != (tls_accept & ZBX_TCP_SEC_TLS_PSK))
+		mbedtls_ssl_conf_ciphersuites(s->tls_ctx->conf, ciphersuites_psk);
+
+	/* TLS handshake */
+
+#if defined(_WINDOWS)
+	zbx_alarm_flag_clear();
+	sec = zbx_time();
+#endif
+	while (0 != (res = mbedtls_ssl_handshake(s->tls_ctx->ctx)))
+	{
+#if defined(_WINDOWS)
+		if (s->timeout < zbx_time() - sec)
+			zbx_alarm_flag_set();
+#endif
+		if (SUCCEED == zbx_alarm_timed_out())
+		{
+			*error = zbx_strdup(*error, "mbedtls_ssl_handshake() timed out");
+			goto out;
+		}
+
+		if (MBEDTLS_ERR_SSL_WANT_READ != res && MBEDTLS_ERR_SSL_WANT_WRITE != res)
+		{
+			if (MBEDTLS_ERR_X509_CERT_VERIFY_FAILED == res)
+			{
+				/* Standard PolarSSL error message might not be very informative in this case. For */
+				/* example, if certificate validity starts in future, PolarSSL 1.3.9 would produce a */
+				/* message "X509 - Certificate verification failed, e.g. CRL, CA or signature check */
+				/* failed" which does not give a precise reason. Here we try to get more detailed */
+				/* reason why peer certificate was rejected by using some knowledge about PolarSSL */
+				/* internals. */
+				zbx_tls_cert_error_msg((unsigned int)s->tls_ctx->ctx->session_negotiate->verify_result,
+						error);
+				zbx_tls_close(s);
+				goto out1;
+			}
+
+			zbx_tls_error_msg(res, "mbedtls_ssl_handshake(): ", error);
+			goto out;
+		}
+	}
+
+	/* Is this TLS conection using certificate or PSK? */
+
+	info = mbedtls_ssl_ciphersuite_from_id(s->tls_ctx->ctx->session->ciphersuite);
+
+	if (MBEDTLS_KEY_EXCHANGE_PSK == info->key_exchange ||
+			MBEDTLS_KEY_EXCHANGE_DHE_PSK == info->key_exchange ||
+			MBEDTLS_KEY_EXCHANGE_ECDHE_PSK == info->key_exchange ||
+			MBEDTLS_KEY_EXCHANGE_RSA_PSK == info->key_exchange)
+	{
+		s->connection_type = ZBX_TCP_SEC_TLS_PSK;
+
+		if (SUCCEED == zabbix_check_log_level(LOG_LEVEL_DEBUG))
+		{
+			/* special print: s->tls_ctx->ctx->psk_identity is not '\0'-terminated */
+			zabbix_log(LOG_LEVEL_DEBUG, "%s() PSK identity: \"%.*s\"", __function_name,
+					(int)s->tls_ctx->conf->psk_identity_len, s->tls_ctx->conf->psk_identity);
+		}
+	}
+	else
+	{
+		s->connection_type = ZBX_TCP_SEC_TLS_CERT;
+
+		/* log peer certificate information for debugging */
+		zbx_log_peer_cert(__function_name, s->tls_ctx);
+
+		/* basic verification of peer certificate was done during handshake */
+
+		/* Issuer and Subject will be verified later, after receiving sender type and host name */
+	}
+
+	if (SUCCEED == zabbix_check_log_level(LOG_LEVEL_DEBUG))
+	{
+		zabbix_log(LOG_LEVEL_DEBUG, "End of %s():SUCCEED (established %s %s)", __function_name,
+				mbedtls_ssl_get_version(s->tls_ctx->ctx), mbedtls_ssl_get_ciphersuite(s->tls_ctx->ctx));
+	}
+
+	return SUCCEED;
+
+out:	/* an error occurred */
+	mbedtls_ssl_free(s->tls_ctx->ctx);
+	zbx_free(s->tls_ctx->ctx);
+out_pre_setup:
+	mbedtls_ssl_config_free(s->tls_ctx->conf);
+	zbx_free(s->tls_ctx->conf);
+	zbx_free(s->tls_ctx);
+out1:
+	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s error:'%s'", __function_name, zbx_result_string(ret),
+			ZBX_NULL2EMPTY_STR(*error));
+	return ret;
+}
 #elif defined(HAVE_GNUTLS)
 int	zbx_tls_accept(zbx_socket_t *s, unsigned int tls_accept, char **error)
 {
@@ -5041,6 +6309,13 @@ out1:
 #	define ZBX_TLS_READ_FUNC_NAME		"ssl_read"
 #	define ZBX_TLS_WANT_WRITE(res)		(POLARSSL_ERR_NET_WANT_WRITE == (res) ? SUCCEED : FAIL)
 #	define ZBX_TLS_WANT_READ(res)		(POLARSSL_ERR_NET_WANT_READ == (res) ? SUCCEED : FAIL)
+#elif defined(HAVE_MBEDTLS21)
+#	define ZBX_TLS_WRITE(ctx, buf, len)	mbedtls_ssl_write(ctx, (const unsigned char *)(buf), len)
+#	define ZBX_TLS_READ(ctx, buf, len)	mbedtls_ssl_read(ctx, (unsigned char *)(buf), len)
+#	define ZBX_TLS_WRITE_FUNC_NAME		"mbedtls_ssl_write"
+#	define ZBX_TLS_READ_FUNC_NAME		"mbedtls_ssl_read"
+#	define ZBX_TLS_WANT_WRITE(res)		(MBEDTLS_ERR_SSL_WANT_WRITE == (res) ? SUCCEED : FAIL)
+#	define ZBX_TLS_WANT_READ(res)		(MBEDTLS_ERR_SSL_WANT_READ == (res) ? SUCCEED : FAIL)
 #elif defined(HAVE_GNUTLS)
 #	define ZBX_TLS_WRITE(ctx, buf, len)	gnutls_record_send(ctx, buf, len)
 #	define ZBX_TLS_READ(ctx, buf, len)	gnutls_record_recv(ctx, buf, len)
@@ -5066,6 +6341,8 @@ ssize_t	zbx_tls_write(zbx_socket_t *s, const char *buf, size_t len, char **error
 #endif
 #if defined(HAVE_POLARSSL)
 	int	res;
+#elif defined(HAVE_MBEDTLS21)
+	int	res;
 #elif defined(HAVE_GNUTLS)
 	ssize_t	res;
 #elif defined(HAVE_OPENSSL)
@@ -5101,6 +6378,16 @@ ssize_t	zbx_tls_write(zbx_socket_t *s, const char *buf, size_t len, char **error
 
 		return ZBX_PROTO_ERROR;
 	}
+#elif defined(HAVE_MBEDTLS21)
+	if (0 > res)
+	{
+		char	err[128];	/* 128 bytes are enough for PolarSSL error messages */
+
+		mbedtls_strerror(res, err, sizeof(err));
+		*error = zbx_dsprintf(*error, "mbedtls_ssl_write() failed: %s", err);
+
+		return ZBX_PROTO_ERROR;
+	}
 #elif defined(HAVE_GNUTLS)
 	if (0 > res)
 	{
@@ -5147,6 +6434,8 @@ ssize_t	zbx_tls_read(zbx_socket_t *s, char *buf, size_t len, char **error)
 #endif
 #if defined(HAVE_POLARSSL)
 	int	res;
+#elif defined(HAVE_MBEDTLS21)
+	int	res;
 #elif defined(HAVE_GNUTLS)
 	ssize_t	res;
 #elif defined(HAVE_OPENSSL)
@@ -5182,6 +6471,16 @@ ssize_t	zbx_tls_read(zbx_socket_t *s, char *buf, size_t len, char **error)
 
 		return ZBX_PROTO_ERROR;
 	}
+#elif defined(HAVE_MBEDTLS21)
+	if (0 > res)
+	{
+		char	err[128];	/* 128 bytes are enough for PolarSSL error messages */
+
+		mbedtls_strerror(res, err, sizeof(err));
+		*error = zbx_dsprintf(*error, "mbedtls_ssl_read() failed: %s", err);
+
+		return ZBX_PROTO_ERROR;
+	}
 #elif defined(HAVE_GNUTLS)
 	if (0 > res)
 	{
@@ -5264,6 +6563,35 @@ void	zbx_tls_close(zbx_socket_t *s)
 		ssl_free(s->tls_ctx->ctx);
 		zbx_free(s->tls_ctx->ctx);
 	}
+#elif defined(HAVE_MBEDTLS21)
+	if (NULL != s->tls_ctx->ctx)
+	{
+#if defined(_WINDOWS)
+		double	sec;
+
+		zbx_alarm_flag_clear();
+		sec = zbx_time();
+#endif
+		while (0 > (res = mbedtls_ssl_close_notify(s->tls_ctx->ctx)))
+		{
+#if defined(_WINDOWS)
+			if (s->timeout < zbx_time() - sec)
+				zbx_alarm_flag_set();
+#endif
+			if (SUCCEED == zbx_alarm_timed_out())
+				break;
+
+			if (MBEDTLS_ERR_SSL_WANT_READ != res && MBEDTLS_ERR_SSL_WANT_WRITE != res)
+			{
+				zabbix_log(LOG_LEVEL_WARNING, "mbedtls_ssl_close_notify() with %s returned error code: %d",
+						s->peer, res);
+				break;
+			}
+		}
+
+		mbedtls_ssl_free(s->tls_ctx->ctx);
+		zbx_free(s->tls_ctx->ctx);
+	}
 #elif defined(HAVE_GNUTLS)
 	if (NULL != s->tls_ctx->ctx)
 	{
@@ -5339,6 +6667,8 @@ int	zbx_tls_get_attr_cert(const zbx_socket_t *s, zbx_tls_conn_attr_t *attr)
 	char			*error = NULL;
 #if defined(HAVE_POLARSSL)
 	const x509_crt		*peer_cert;
+#elif defined(HAVE_MBEDTLS21)
+	const mbedtls_x509_crt		*peer_cert;
 #elif defined(HAVE_GNUTLS)
 	gnutls_x509_crt_t	peer_cert;
 	gnutls_x509_dn_t	dn;
@@ -5367,6 +6697,26 @@ int	zbx_tls_get_attr_cert(const zbx_socket_t *s, zbx_tls_conn_attr_t *attr)
 		zbx_free(error);
 		return FAIL;
 	}
+#elif defined(HAVE_MBEDTLS21)
+	if (NULL == (peer_cert = mbedtls_ssl_get_peer_cert(s->tls_ctx->ctx)))
+	{
+		zabbix_log(LOG_LEVEL_WARNING, "no peer certificate, mbedtls_ssl_get_peer_cert() returned NULL");
+		return FAIL;
+	}
+
+	if (SUCCEED != zbx_x509_dn_gets(&peer_cert->issuer, attr->issuer, sizeof(attr->issuer), &error))
+	{
+		zabbix_log(LOG_LEVEL_WARNING, "error while getting issuer name: \"%s\"", error);
+		zbx_free(error);
+		return FAIL;
+	}
+
+	if (SUCCEED != zbx_x509_dn_gets(&peer_cert->subject, attr->subject, sizeof(attr->subject), &error))
+	{
+		zabbix_log(LOG_LEVEL_WARNING, "error while getting subject name: \"%s\"", error);
+		zbx_free(error);
+		return FAIL;
+	}
 #elif defined(HAVE_GNUTLS)
 	/* here is some inefficiency - we do not know will it be required to verify peer certificate issuer */
 	/* and subject - but we prepare for it */
@@ -5457,6 +6807,9 @@ int	zbx_tls_get_attr_psk(const zbx_socket_t *s, zbx_tls_conn_attr_t *attr)
 #if defined(HAVE_POLARSSL)
 	attr->psk_identity = (char *)s->tls_ctx->ctx->psk_identity;
 	attr->psk_identity_len = s->tls_ctx->ctx->psk_identity_len;
+#elif defined(HAVE_MBEDTLS21)
+	attr->psk_identity = (char *)s->tls_ctx->conf->psk_identity;
+	attr->psk_identity_len = s->tls_ctx->conf->psk_identity_len;
 #elif defined(HAVE_GNUTLS)
 	if (NULL != (attr->psk_identity = gnutls_psk_server_get_username(s->tls_ctx->ctx)))
 		attr->psk_identity_len = strlen(attr->psk_identity);
@@ -5497,6 +6850,19 @@ void	zbx_tls_pass_vars(ZBX_THREAD_SENDVAL_TLS_ARGS *args)
 	args->ctr_drbg = ctr_drbg;
 	args->ciphersuites_cert = ciphersuites_cert;
 	args->ciphersuites_psk = ciphersuites_psk;
+#elif defined(HAVE_MBEDTLS21)
+	args->my_psk = my_psk;
+	args->my_psk_len = my_psk_len;
+	args->my_psk_identity = my_psk_identity;
+	args->my_psk_identity_len = my_psk_identity_len;
+	args->ca_cert = ca_cert;
+	args->crl = crl;
+	args->my_cert = my_cert;
+	args->my_priv_key = my_priv_key;
+	args->entropy = entropy;
+	args->ctr_drbg = ctr_drbg;
+	args->ciphersuites_cert = ciphersuites_cert;
+	args->ciphersuites_psk = ciphersuites_psk;
 #elif defined(HAVE_GNUTLS)
 	args->my_cert_creds = my_cert_creds;
 	args->my_psk_client_creds = my_psk_client_creds;
@@ -5536,6 +6902,19 @@ void	zbx_tls_take_vars(ZBX_THREAD_SENDVAL_TLS_ARGS *args)
 	ctr_drbg = args->ctr_drbg;
 	ciphersuites_cert = args->ciphersuites_cert;
 	ciphersuites_psk = args->ciphersuites_psk;
+#elif defined(HAVE_MBEDTLS21)
+	my_psk = args->my_psk;
+	my_psk_len = args->my_psk_len;
+	my_psk_identity = args->my_psk_identity;
+	my_psk_identity_len = args->my_psk_identity_len;
+	ca_cert = args->ca_cert;
+	crl = args->crl;
+	my_cert = args->my_cert;
+	my_priv_key = args->my_priv_key;
+	entropy = args->entropy;
+	ctr_drbg = args->ctr_drbg;
+	ciphersuites_cert = args->ciphersuites_cert;
+	ciphersuites_psk = args->ciphersuites_psk;
 #elif defined(HAVE_GNUTLS)
 	my_cert_creds = args->my_cert_creds;
 	my_psk_client_creds = args->my_psk_client_creds;
diff --git a/src/libs/zbxcrypto/tls.h b/src/libs/zbxcrypto/tls.h
index 48b02a8..ad05172 100644
--- a/src/libs/zbxcrypto/tls.h
+++ b/src/libs/zbxcrypto/tls.h
@@ -20,7 +20,7 @@
 #ifndef ZABBIX_TLS_H
 #define ZABBIX_TLS_H
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 
 #if defined(_WINDOWS)
 /* Typical thread is long-running, if necessary, it initializes TLS for itself. Zabbix sender is an exception. If */
@@ -32,6 +32,10 @@
 #	include <polarssl/entropy.h>
 #	include <polarssl/ctr_drbg.h>
 #	include <polarssl/ssl.h>
+#elif defined(HAVE_MBEDTLS21)
+#	include <mbedtls/entropy.h>
+#	include <mbedtls/ctr_drbg.h>
+#	include <mbedtls/ssl.h>
 #elif defined(HAVE_GNUTLS)
 #	include <gnutls/gnutls.h>
 #elif defined(HAVE_OPENSSL)
@@ -53,6 +57,19 @@ typedef struct
 	ctr_drbg_context	*ctr_drbg;
 	int			*ciphersuites_cert;
 	int			*ciphersuites_psk;
+#elif defined(HAVE_MBEDTLS21)
+	char				*my_psk;
+	size_t				my_psk_len;
+	char				*my_psk_identity;
+	size_t				my_psk_identity_len;
+	mbedtls_x509_crt		*ca_cert;
+	mbedtls_x509_crl		*crl;
+	mbedtls_x509_crt		*my_cert;
+	mbedtls_pk_context		*my_priv_key;
+	mbedtls_entropy_context		*entropy;
+	mbedtls_ctr_drbg_context	*ctr_drbg;
+	int				*ciphersuites_cert;
+	int				*ciphersuites_psk;
 #elif defined(HAVE_GNUTLS)
 	gnutls_certificate_credentials_t	my_cert_creds;
 	gnutls_psk_client_credentials_t		my_psk_client_creds;
@@ -80,6 +97,6 @@ void	zbx_tls_init_child(void);
 void	zbx_tls_free(void);
 void	zbx_tls_free_on_signal(void);
 
-#endif	/* #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL) */
+#endif	/* #if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL) */
 
 #endif	/* ZABBIX_TLS_H */
diff --git a/src/libs/zbxcrypto/tls_tcp.h b/src/libs/zbxcrypto/tls_tcp.h
index 104af9d..2abd8ba 100644
--- a/src/libs/zbxcrypto/tls_tcp.h
+++ b/src/libs/zbxcrypto/tls_tcp.h
@@ -20,7 +20,7 @@
 #ifndef ZABBIX_TLS_TCP_H
 #define ZABBIX_TLS_TCP_H
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 int	zbx_tls_connect(zbx_socket_t *s, unsigned int tls_connect, char *tls_arg1, char *tls_arg2, char **error);
 int	zbx_tls_accept(zbx_socket_t *s, unsigned int tls_accept, char **error);
 ssize_t	zbx_tls_write(zbx_socket_t *s, const char *buf, size_t len, char **error);
diff --git a/src/libs/zbxcrypto/tls_tcp_active.h b/src/libs/zbxcrypto/tls_tcp_active.h
index fcd1cc5..a1cd447 100644
--- a/src/libs/zbxcrypto/tls_tcp_active.h
+++ b/src/libs/zbxcrypto/tls_tcp_active.h
@@ -20,7 +20,7 @@
 #ifndef ZABBIX_TLS_TCP_ACTIVE_H
 #define ZABBIX_TLS_TCP_ACTIVE_H
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 typedef struct
 {
 	const char	*psk_identity;
diff --git a/src/libs/zbxdbcache/dbconfig.c b/src/libs/zbxdbcache/dbconfig.c
index efb477d..e8237fe 100644
--- a/src/libs/zbxdbcache/dbconfig.c
+++ b/src/libs/zbxdbcache/dbconfig.c
@@ -809,14 +809,14 @@ static void	DCsync_hosts(zbx_dbsync_t *sync)
 	time_t			now;
 	signed char		ipmi_authtype;
 	unsigned char		ipmi_privilege;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	ZBX_DC_PSK		*psk_i, psk_i_local;
 	zbx_ptr_pair_t		*psk_owner, psk_owner_local;
 	zbx_hashset_t		psk_owners;
 #endif
 	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_hashset_create(&psk_owners, 0, ZBX_DEFAULT_PTR_HASH_FUNC, ZBX_DEFAULT_PTR_COMPARE_FUNC);
 #endif
 	now = time(NULL);
@@ -889,7 +889,7 @@ static void	DCsync_hosts(zbx_dbsync_t *sync)
 
 		DCstrpool_replace(found, &host->host, row[2]);
 		DCstrpool_replace(found, &host->name, row[23]);
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		DCstrpool_replace(found, &host->tls_issuer, row[31]);
 		DCstrpool_replace(found, &host->tls_subject, row[32]);
 
@@ -1273,7 +1273,7 @@ done:
 		zbx_strpool_release(host->snmp_error);
 		zbx_strpool_release(host->ipmi_error);
 		zbx_strpool_release(host->jmx_error);
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		zbx_strpool_release(host->tls_issuer);
 		zbx_strpool_release(host->tls_subject);
 
@@ -1294,7 +1294,7 @@ done:
 		zbx_hashset_remove_direct(&config->hosts, host);
 	}
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_hashset_destroy(&psk_owners);
 #endif
 
@@ -3674,7 +3674,7 @@ void	DCsync_configuration(unsigned char mode)
 				config->hosts_h.num_data, config->hosts_h.num_slots);
 		zabbix_log(LOG_LEVEL_DEBUG, "%s() hosts_p    : %d (%d slots)", __function_name,
 				config->hosts_p.num_data, config->hosts_p.num_slots);
-	#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+	#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		zabbix_log(LOG_LEVEL_DEBUG, "%s() psks       : %d (%d slots)", __function_name,
 				config->psks.num_data, config->psks.num_slots);
 	#endif
@@ -4065,7 +4065,7 @@ static int	__config_regexp_compare(const void *d1, const void *d2)
 	return r1->name == r2->name ? 0 : strcmp(r1->name, r2->name);
 }
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 static zbx_hash_t	__config_psk_hash(const void *data)
 {
 	const ZBX_DC_PSK	*psk_i = (const ZBX_DC_PSK *)data;
@@ -4178,7 +4178,7 @@ void	init_configuration_cache(void)
 			__config_mem_realloc_func,
 			__config_mem_free_func);
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	CREATE_HASHSET_EXT(config->psks, 0, __config_psk_hash, __config_psk_compare);
 #endif
 	for (i = 0; i < CONFIG_TIMER_FORKS; i++)
@@ -4329,7 +4329,7 @@ static void	DCget_host(DC_HOST *dst_host, const ZBX_DC_HOST *src_host)
 	strscpy(dst_host->jmx_error, src_host->jmx_error);
 	dst_host->tls_connect = src_host->tls_connect;
 	dst_host->tls_accept = src_host->tls_accept;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	strscpy(dst_host->tls_issuer, src_host->tls_issuer);
 	strscpy(dst_host->tls_subject, src_host->tls_subject);
 
@@ -4421,7 +4421,7 @@ int	DCget_host_by_hostid(DC_HOST *host, zbx_uint64_t hostid)
 int	DCcheck_proxy_permissions(const char *host, const zbx_socket_t *sock, zbx_uint64_t *hostid, char **error)
 {
 	const ZBX_DC_HOST	*dc_host;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_conn_attr_t	attr;
 
 	if (ZBX_TCP_SEC_TLS_CERT == sock->connection_type)
@@ -4473,7 +4473,7 @@ int	DCcheck_proxy_permissions(const char *host, const zbx_socket_t *sock, zbx_ui
 		return FAIL;
 	}
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	if (ZBX_TCP_SEC_TLS_CERT == sock->connection_type)
 	{
 		/* simplified match, not compliant with RFC 4517, 4518 */
@@ -4521,7 +4521,7 @@ int	DCcheck_proxy_permissions(const char *host, const zbx_socket_t *sock, zbx_ui
 	return SUCCEED;
 }
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 /******************************************************************************
  *                                                                            *
  * Function: DCget_psk_by_identity                                            *
@@ -6898,7 +6898,7 @@ static void	DCget_proxy(DC_PROXY *dst_proxy, ZBX_DC_PROXY *src_proxy)
 		strscpy(dst_proxy->host, host->host);
 		dst_proxy->tls_connect = host->tls_connect;
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		if (ZBX_TCP_SEC_TLS_CERT == host->tls_connect)
 		{
 			strscpy(dst_proxy->tls_arg1, host->tls_issuer);
@@ -6922,7 +6922,7 @@ static void	DCget_proxy(DC_PROXY *dst_proxy, ZBX_DC_PROXY *src_proxy)
 		/* process_proxy(). So, this branch should never happen. */
 		*dst_proxy->host = '\0';
 		dst_proxy->tls_connect = ZBX_TCP_SEC_TLS_PSK;	/* set PSK to deliberately fail in this case */
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		*dst_proxy->tls_arg1 = '\0';
 		*dst_proxy->tls_arg2 = '\0';
 #endif
diff --git a/src/libs/zbxdbcache/dbconfig.h b/src/libs/zbxdbcache/dbconfig.h
index aa0ec44..fb207a1 100644
--- a/src/libs/zbxdbcache/dbconfig.h
+++ b/src/libs/zbxdbcache/dbconfig.h
@@ -214,7 +214,7 @@ ZBX_DC_CALCITEM;
 
 typedef zbx_item_history_value_t	ZBX_DC_DELTAITEM;
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 typedef struct
 {
 	const char	*tls_psk_identity;	/* pre-shared key identity           */
@@ -267,7 +267,7 @@ typedef struct
 	/* 'tls_connect' and 'tls_accept' must be respected even if encryption support is not compiled in */
 	unsigned char	tls_connect;
 	unsigned char	tls_accept;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	const char	*tls_issuer;
 	const char	*tls_subject;
 	ZBX_DC_PSK	*tls_dc_psk;
@@ -487,7 +487,7 @@ typedef struct
 	zbx_hashset_t		expressions;
 	zbx_hashset_t		actions;
 	zbx_hashset_t		action_conditions;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_hashset_t		psks;			/* for keeping PSK-identity and PSK pairs and for searching */
 							/* by PSK identity */
 #endif
diff --git a/src/libs/zbxdbcache/dbconfig_dump.c b/src/libs/zbxdbcache/dbconfig_dump.c
index 47b9d4b..da47087 100644
--- a/src/libs/zbxdbcache/dbconfig_dump.c
+++ b/src/libs/zbxdbcache/dbconfig_dump.c
@@ -119,7 +119,7 @@ static void	DCdump_hosts(ZBX_DC_CONFIG *config)
 
 		/* 'tls_connect' and 'tls_accept' must be respected even if encryption support is not compiled in */
 		zabbix_log(LOG_LEVEL_TRACE, "  tls:[connect:%u accept:%u]", host->tls_connect, host->tls_accept);
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		zabbix_log(LOG_LEVEL_TRACE, "  tls:[issuer:'%s' subject:'%s']", host->tls_issuer, host->tls_subject);
 
 		if (NULL != host->tls_dc_psk)
diff --git a/src/libs/zbxdbcache/dbsync.c b/src/libs/zbxdbcache/dbsync.c
index 74cddf3..815840f 100644
--- a/src/libs/zbxdbcache/dbsync.c
+++ b/src/libs/zbxdbcache/dbsync.c
@@ -423,7 +423,7 @@ static int	dbsync_compare_host(ZBX_DC_HOST *host, const DB_ROW row)
 	if (FAIL == dbsync_compare_str(row[23], host->name))
 		return FAIL;
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	if (FAIL == dbsync_compare_str(row[31], host->tls_issuer))
 		return FAIL;
 
@@ -503,7 +503,7 @@ int	zbx_dbsync_compare_hosts(zbx_dbsync_t *sync)
 	zbx_uint64_t		rowid;
 	ZBX_DC_HOST		*host;
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	if (NULL == (result = DBselect(
 			"select hostid,proxy_hostid,host,ipmi_authtype,ipmi_privilege,ipmi_username,"
 				"ipmi_password,maintenance_status,maintenance_type,maintenance_from,"
diff --git a/src/libs/zbxdbhigh/proxy.c b/src/libs/zbxdbhigh/proxy.c
index c6877e1..e499773 100644
--- a/src/libs/zbxdbhigh/proxy.c
+++ b/src/libs/zbxdbhigh/proxy.c
@@ -177,7 +177,7 @@ int	check_access_passive_proxy(zbx_socket_t *sock, int send_response, const char
 		return FAIL;
 	}
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	if (ZBX_TCP_SEC_TLS_CERT == sock->connection_type && SUCCEED != zbx_check_server_issuer_subject(sock, &msg))
 	{
 		zabbix_log(LOG_LEVEL_WARNING, "%s from server is not allowed: %s", req, msg);
@@ -2044,12 +2044,12 @@ void	process_mass_data(zbx_socket_t *sock, zbx_uint64_t proxy_hostid, AGENT_VALU
 	int			*lastclocks = NULL, *errcodes = NULL, *mtimes = NULL, *errcodes2 = NULL,
 				flag_host_allow = 0;
 	size_t			num = 0;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_conn_attr_t	attr;
 #endif
 	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	if (0 == proxy_hostid &&
 			((ZBX_TCP_SEC_TLS_CERT == sock->connection_type &&
 				SUCCEED != zbx_tls_get_attr_cert(sock, &attr)) ||
@@ -2157,7 +2157,7 @@ void	process_mass_data(zbx_socket_t *sock, zbx_uint64_t proxy_hostid, AGENT_VALU
 					continue;
 				}
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 				if (ZBX_TCP_SEC_TLS_CERT == sock->connection_type)
 				{
 					/* simplified match, not compliant with RFC 4517, 4518 */
diff --git a/src/libs/zbxnix/coredump.c b/src/libs/zbxnix/coredump.c
index fc32d73..f5c8917 100644
--- a/src/libs/zbxnix/coredump.c
+++ b/src/libs/zbxnix/coredump.c
@@ -21,7 +21,7 @@
 #include "log.h"
 #include "zbxnix.h"
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 /******************************************************************************
  *                                                                            *
  * Function: zbx_coredump_disable                                             *
diff --git a/src/libs/zbxnix/sighandler.c b/src/libs/zbxnix/sighandler.c
index 83ddb38..ccf8c14 100644
--- a/src/libs/zbxnix/sighandler.c
+++ b/src/libs/zbxnix/sighandler.c
@@ -45,7 +45,7 @@ static void	fatal_signal_handler(int sig, siginfo_t *siginfo, void *context)
 			SIG_CHECKED_FIELD_TYPE(siginfo, si_addr, void *));
 	print_fatal_info(sig, siginfo, context);
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_free_on_signal();
 #endif
 	exit(EXIT_FAILURE);
@@ -93,7 +93,7 @@ static void	terminate_signal_handler(int sig, siginfo_t *siginfo, void *context)
 		if (SIGINT == sig)
 			return;
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		zbx_tls_free_on_signal();
 #endif
 		exit(EXIT_FAILURE);
@@ -112,7 +112,7 @@ static void	terminate_signal_handler(int sig, siginfo_t *siginfo, void *context)
 					SIG_CHECKED_FIELD(siginfo, si_uid),
 					SIG_CHECKED_FIELD(siginfo, si_code));
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 			zbx_tls_free_on_signal();
 #endif
 			zbx_on_exit();
@@ -133,7 +133,7 @@ static void	child_signal_handler(int sig, siginfo_t *siginfo, void *context)
 
 	if (!SIG_PARENT_PROCESS)
 	{
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		zbx_tls_free_on_signal();
 #endif
 		exit(EXIT_FAILURE);
@@ -145,7 +145,7 @@ static void	child_signal_handler(int sig, siginfo_t *siginfo, void *context)
 		zabbix_log(LOG_LEVEL_CRIT, "One child process died (PID:%d,exitcode/signal:%d). Exiting ...",
 				SIG_CHECKED_FIELD(siginfo, si_pid), SIG_CHECKED_FIELD(siginfo, si_status));
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		zbx_tls_free_on_signal();
 #endif
 		zbx_on_exit();
diff --git a/src/zabbix_agent/active.c b/src/zabbix_agent/active.c
index 9e2348f..efca681 100644
--- a/src/zabbix_agent/active.c
+++ b/src/zabbix_agent/active.c
@@ -569,7 +569,7 @@ static int	refresh_active_checks(const char *host, unsigned short port)
 			tls_arg1 = NULL;
 			tls_arg2 = NULL;
 			break;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		case ZBX_TCP_SEC_TLS_CERT:
 			tls_arg1 = CONFIG_TLS_SERVER_CERT_ISSUER;
 			tls_arg2 = CONFIG_TLS_SERVER_CERT_SUBJECT;
@@ -751,7 +751,7 @@ static int	send_buffer(const char *host, unsigned short port)
 			tls_arg1 = NULL;
 			tls_arg2 = NULL;
 			break;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		case ZBX_TCP_SEC_TLS_CERT:
 			tls_arg1 = CONFIG_TLS_SERVER_CERT_ISSUER;
 			tls_arg2 = CONFIG_TLS_SERVER_CERT_SUBJECT;
@@ -1630,7 +1630,7 @@ ZBX_THREAD_ENTRY(active_checks_thread, args)
 
 	zbx_free(args);
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_init_child();
 #endif
 	init_active_metrics();
diff --git a/src/zabbix_agent/listener.c b/src/zabbix_agent/listener.c
index 2945c93..5bbf30b 100644
--- a/src/zabbix_agent/listener.c
+++ b/src/zabbix_agent/listener.c
@@ -102,7 +102,7 @@ static void	process_listener(zbx_socket_t *s)
 
 ZBX_THREAD_ENTRY(listener_thread, args)
 {
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	char		*msg = NULL;
 #endif
 	int		ret;
@@ -122,7 +122,7 @@ ZBX_THREAD_ENTRY(listener_thread, args)
 
 	zbx_free(args);
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_init_child();
 #endif
 	while (ZBX_IS_RUNNING())
@@ -137,7 +137,7 @@ ZBX_THREAD_ENTRY(listener_thread, args)
 
 			if (SUCCEED == (ret = zbx_tcp_check_security(&s, CONFIG_HOSTS_ALLOWED, 0)))
 			{
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 				if (ZBX_TCP_SEC_TLS_CERT != s.connection_type ||
 						SUCCEED == (ret = zbx_check_server_issuer_subject(&s, &msg)))
 #endif
@@ -152,7 +152,7 @@ ZBX_THREAD_ENTRY(listener_thread, args)
 		if (SUCCEED == ret || EINTR == zbx_socket_last_error())
 			goto next;
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		if (NULL != msg)
 		{
 			zabbix_log(LOG_LEVEL_WARNING, "failed to accept an incoming connection: %s", msg);
diff --git a/src/zabbix_agent/zabbix_agentd.c b/src/zabbix_agent/zabbix_agentd.c
index 0e0dedb..496b0a7 100644
--- a/src/zabbix_agent/zabbix_agentd.c
+++ b/src/zabbix_agent/zabbix_agentd.c
@@ -583,7 +583,7 @@ static void	zbx_validate_config(ZBX_TASK_EX *task)
 	if (SUCCEED != zbx_validate_log_parameters(task))
 		err = 1;
 
-#if !(defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
+#if !(defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
 	err |= (FAIL == check_cfg_feature_str("TLSConnect", CONFIG_TLS_CONNECT, "TLS support"));
 	err |= (FAIL == check_cfg_feature_str("TLSAccept", CONFIG_TLS_ACCEPT, "TLS support"));
 	err |= (FAIL == check_cfg_feature_str("TLSCAFile", CONFIG_TLS_CA_FILE, "TLS support"));
@@ -797,7 +797,7 @@ static void	zbx_load_config(int requirement, ZBX_TASK_EX *task)
 	if (ZBX_CFG_FILE_REQUIRED == requirement)
 	{
 		zbx_validate_config(task);
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		zbx_tls_validate_config();
 #endif
 	}
@@ -873,7 +873,7 @@ int	MAIN_ZABBIX_ENTRY(int flags)
 #else
 #	define IPV6_FEATURE_STATUS	" NO"
 #endif
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 #	define TLS_FEATURE_STATUS	"YES"
 #else
 #	define TLS_FEATURE_STATUS	" NO"
@@ -890,7 +890,7 @@ int	MAIN_ZABBIX_ENTRY(int flags)
 	zabbix_log(LOG_LEVEL_INFORMATION, "using configuration file: %s", CONFIG_FILE);
 
 #ifndef _WINDOWS
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	if (SUCCEED != zbx_coredump_disable())
 	{
 		zabbix_log(LOG_LEVEL_CRIT, "cannot disable core dump, exiting...");
@@ -920,7 +920,7 @@ int	MAIN_ZABBIX_ENTRY(int flags)
 #endif
 	zbx_free_config();
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_init_parent();
 #endif
 	/* --- START THREADS ---*/
@@ -1075,7 +1075,7 @@ void	zbx_on_exit(void)
 
 	zbx_free_service_resources();
 
-#if defined(_WINDOWS) && (defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
+#if defined(_WINDOWS) && (defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
 	zbx_tls_free();
 	zbx_tls_library_deinit();	/* deinitialize crypto library from parent thread */
 #endif
diff --git a/src/zabbix_get/zabbix_get.c b/src/zabbix_get/zabbix_get.c
index 1f81951..6522aa6 100644
--- a/src/zabbix_get/zabbix_get.c
+++ b/src/zabbix_get/zabbix_get.c
@@ -35,7 +35,7 @@ const char	title_message[] = "zabbix_get";
 const char	syslog_app_name[] = "zabbix_get";
 const char	*usage_message[] = {
 	"-s host-name-or-IP", "[-p port-number]", "[-I IP-address]", "-k item-key", NULL,
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	"-s host-name-or-IP", "[-p port-number]", "[-I IP-address]", "--tls-connect cert", "--tls-ca-file CA-file",
 	"[--tls-crl-file CRL-file]", "[--tls-agent-cert-issuer cert-issuer]", "[--tls-agent-cert-subject cert-subject]",
 	"--tls-cert-file cert-file", "--tls-key-file key-file", "-k item-key", NULL,
@@ -64,7 +64,7 @@ const char	*help_message[] = {
 	"  -V --version               Display version number",
 	"",
 	"TLS connection options:",
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	"  --tls-connect value        How to connect to agent. Values:",
 	"                               unencrypted - connect without encryption",
 	"                                             (default)",
@@ -100,7 +100,7 @@ const char	*help_message[] = {
 	"",
 	"Example(s):",
 	"  zabbix_get -s 127.0.0.1 -p " ZBX_DEFAULT_AGENT_PORT_STR " -k \"system.cpu.load[all,avg1]\"",
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	"",
 	"  zabbix_get -s 127.0.0.1 -p " ZBX_DEFAULT_AGENT_PORT_STR " -k \"system.cpu.load[all,avg1]\" \\",
 	"    --tls-connect cert --tls-ca-file /home/zabbix/zabbix_ca_file \\",
@@ -187,7 +187,7 @@ static void	get_signal_handler(int sig)
 	if (SIGALRM == sig)
 		zbx_error("Timeout while executing operation");
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	if (ZBX_TCP_SEC_UNENCRYPTED != configured_tls_connect_mode)
 		zbx_tls_free_on_signal();
 #endif
@@ -220,7 +220,7 @@ static int	get_value(const char *source_ip, const char *host, unsigned short por
 			tls_arg1 = NULL;
 			tls_arg2 = NULL;
 			break;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		case ZBX_TCP_SEC_TLS_CERT:
 			tls_arg1 = CONFIG_TLS_SERVER_CERT_ISSUER;
 			tls_arg2 = CONFIG_TLS_SERVER_CERT_SUBJECT;
@@ -298,7 +298,7 @@ int	main(int argc, char **argv)
 	char		*host = NULL, *key = NULL, *source_ip = NULL, ch;
 	unsigned short	opt_count[256] = {0}, port = ZBX_DEFAULT_AGENT_PORT;
 
-#if !defined(_WINDOWS) && (defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
+#if !defined(_WINDOWS) && (defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
 	if (SUCCEED != zbx_coredump_disable())
 	{
 		zbx_error("cannot disable core dump, exiting...");
@@ -337,7 +337,7 @@ int	main(int argc, char **argv)
 				version();
 				exit(EXIT_SUCCESS);
 				break;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 			case '1':
 				CONFIG_TLS_CONNECT = zbx_strdup(CONFIG_TLS_CONNECT, zbx_optarg);
 				break;
@@ -434,7 +434,7 @@ int	main(int argc, char **argv)
 			NULL != CONFIG_TLS_CERT_FILE || NULL != CONFIG_TLS_KEY_FILE ||
 			NULL != CONFIG_TLS_PSK_IDENTITY || NULL != CONFIG_TLS_PSK_FILE)
 	{
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		zbx_tls_validate_config();
 
 		if (ZBX_TCP_SEC_UNENCRYPTED != configured_tls_connect_mode)
@@ -458,7 +458,7 @@ out:
 	zbx_free(host);
 	zbx_free(key);
 	zbx_free(source_ip);
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	if (ZBX_TCP_SEC_UNENCRYPTED != configured_tls_connect_mode)
 	{
 		zbx_tls_free();
diff --git a/src/zabbix_proxy/datasender/datasender.c b/src/zabbix_proxy/datasender/datasender.c
index 91f40c8..2c356cb 100644
--- a/src/zabbix_proxy/datasender/datasender.c
+++ b/src/zabbix_proxy/datasender/datasender.c
@@ -150,7 +150,7 @@ ZBX_THREAD_ENTRY(datasender_thread, args)
 	zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
 			server_num, get_process_type_string(process_type), process_num);
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_init_child();
 #endif
 	zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type));
diff --git a/src/zabbix_proxy/heart/heart.c b/src/zabbix_proxy/heart/heart.c
index d9a910e..6c92a15 100644
--- a/src/zabbix_proxy/heart/heart.c
+++ b/src/zabbix_proxy/heart/heart.c
@@ -87,7 +87,7 @@ ZBX_THREAD_ENTRY(heart_thread, args)
 	zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
 			server_num, get_process_type_string(process_type), process_num);
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_init_child();
 #endif
 	last_stat_time = time(NULL);
diff --git a/src/zabbix_proxy/proxy.c b/src/zabbix_proxy/proxy.c
index 4069cf3..ee331fc 100644
--- a/src/zabbix_proxy/proxy.c
+++ b/src/zabbix_proxy/proxy.c
@@ -496,7 +496,7 @@ static void	zbx_validate_config(ZBX_TASK_EX *task)
 	if (SUCCEED != zbx_validate_log_parameters(task))
 		err = 1;
 
-#if !(defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
+#if !(defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
 	err |= (FAIL == check_cfg_feature_str("TLSConnect", CONFIG_TLS_CONNECT, "TLS support"));
 	err |= (FAIL == check_cfg_feature_str("TLSAccept", CONFIG_TLS_ACCEPT, "TLS support"));
 	err |= (FAIL == check_cfg_feature_str("TLSCAFile", CONFIG_TLS_CA_FILE, "TLS support"));
@@ -692,7 +692,7 @@ static void	zbx_load_config(ZBX_TASK_EX *task)
 	CONFIG_LOG_TYPE = zbx_get_log_type(CONFIG_LOG_TYPE_STR);
 
 	zbx_validate_config(task);
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_validate_config();
 #endif
 }
@@ -853,7 +853,7 @@ int	MAIN_ZABBIX_ENTRY(int flags)
 #else
 #	define IPV6_FEATURE_STATUS 	" NO"
 #endif
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 #	define TLS_FEATURE_STATUS	"YES"
 #else
 #	define TLS_FEATURE_STATUS	" NO"
@@ -876,7 +876,7 @@ int	MAIN_ZABBIX_ENTRY(int flags)
 
 	zabbix_log(LOG_LEVEL_INFORMATION, "using configuration file: %s", CONFIG_FILE);
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	if (SUCCEED != zbx_coredump_disable())
 	{
 		zabbix_log(LOG_LEVEL_CRIT, "cannot disable core dump, exiting...");
@@ -939,7 +939,7 @@ int	MAIN_ZABBIX_ENTRY(int flags)
 		}
 	}
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_init_parent();
 #endif
 	zabbix_log(LOG_LEVEL_INFORMATION, "proxy #0 started [main process]");
diff --git a/src/zabbix_proxy/proxyconfig/proxyconfig.c b/src/zabbix_proxy/proxyconfig/proxyconfig.c
index d1f9b3a..d3d1ca1 100644
--- a/src/zabbix_proxy/proxyconfig/proxyconfig.c
+++ b/src/zabbix_proxy/proxyconfig/proxyconfig.c
@@ -146,7 +146,7 @@ ZBX_THREAD_ENTRY(proxyconfig_thread, args)
 	zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
 			server_num, get_process_type_string(process_type), process_num);
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_init_child();
 #endif
 	zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type));
diff --git a/src/zabbix_proxy/servercomms.c b/src/zabbix_proxy/servercomms.c
index 524ef70..51ae023 100644
--- a/src/zabbix_proxy/servercomms.c
+++ b/src/zabbix_proxy/servercomms.c
@@ -29,7 +29,7 @@
 
 extern unsigned int	configured_tls_connect_mode;
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 extern char	*CONFIG_TLS_SERVER_CERT_ISSUER;
 extern char	*CONFIG_TLS_SERVER_CERT_SUBJECT;
 extern char	*CONFIG_TLS_PSK_IDENTITY;
@@ -49,7 +49,7 @@ int	connect_to_server(zbx_socket_t *sock, int timeout, int retry_interval)
 			tls_arg1 = NULL;
 			tls_arg2 = NULL;
 			break;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		case ZBX_TCP_SEC_TLS_CERT:
 			tls_arg1 = CONFIG_TLS_SERVER_CERT_ISSUER;
 			tls_arg2 = CONFIG_TLS_SERVER_CERT_SUBJECT;
diff --git a/src/zabbix_sender/zabbix_sender.c b/src/zabbix_sender/zabbix_sender.c
index ccfa873..11335c4 100644
--- a/src/zabbix_sender/zabbix_sender.c
+++ b/src/zabbix_sender/zabbix_sender.c
@@ -42,7 +42,7 @@ const char	*usage_message[] = {
 	NULL,
 	"[-v]", "-c config-file", "[-z server]", "[-p port]", "[-I IP-address]", "[-s host]", "[-T]", "[-r]",
 	"-i input-file", NULL,
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	"[-v]", "-z server", "[-p port]", "[-I IP-address]", "-s host", "--tls-connect cert", "--tls-ca-file CA-file",
 	"[--tls-crl-file CRL-file]", "[--tls-server-cert-issuer cert-issuer]",
 	"[--tls-server-cert-subject cert-subject]", "--tls-cert-file cert-file", "--tls-key-file key-file", "-k key",
@@ -126,7 +126,7 @@ const char	*help_message[] = {
 	"  -V --version               Display version number",
 	"",
 	"TLS connection options:",
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	"  --tls-connect value        How to connect to server or proxy. Values:",
 	"                               unencrypted - connect without encryption",
 	"                                             (default)",
@@ -162,7 +162,7 @@ const char	*help_message[] = {
 	"",
 	"Example(s):",
 	"  zabbix_sender -z 127.0.0.1 -s \"Linux DB3\" -k db.connections -o 43",
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	"",
 	"  zabbix_sender -z 127.0.0.1 -s \"Linux DB3\" -k db.connections -o 43 \\",
 	"    --tls-connect cert --tls-ca-file /home/zabbix/zabbix_ca_file \\",
@@ -263,7 +263,7 @@ typedef struct
 	char		*server;
 	unsigned short	port;
 	struct zbx_json	json;
-#if defined(_WINDOWS) && (defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
+#if defined(_WINDOWS) && (defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
 	ZBX_THREAD_SENDVAL_TLS_ARGS	tls_vars;
 #endif
 	int		sync_timestamp;
@@ -456,7 +456,7 @@ static	ZBX_THREAD_ENTRY(send_value, args)
 
 	sendval_args = (ZBX_THREAD_SENDVAL_ARGS *)((zbx_thread_args_t *)args)->args;
 
-#if defined(_WINDOWS) && (defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
+#if defined(_WINDOWS) && (defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
 	if (ZBX_TCP_SEC_UNENCRYPTED != configured_tls_connect_mode)
 	{
 		/* take TLS data passed from 'main' thread */
@@ -476,7 +476,7 @@ static	ZBX_THREAD_ENTRY(send_value, args)
 			tls_arg1 = NULL;
 			tls_arg2 = NULL;
 			break;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		case ZBX_TCP_SEC_TLS_CERT:
 			tls_arg1 = CONFIG_TLS_SERVER_CERT_ISSUER;
 			tls_arg2 = CONFIG_TLS_SERVER_CERT_SUBJECT;
@@ -683,7 +683,7 @@ static void	parse_commandline(int argc, char **argv)
 				else if (LOG_LEVEL_DEBUG > CONFIG_LOG_LEVEL)
 					CONFIG_LOG_LEVEL = LOG_LEVEL_DEBUG;
 				break;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 			case '1':
 				CONFIG_TLS_CONNECT = zbx_strdup(CONFIG_TLS_CONNECT, zbx_optarg);
 				break;
@@ -1019,7 +1019,7 @@ int	main(int argc, char **argv)
 
 	zabbix_open_log(LOG_TYPE_UNDEFINED, CONFIG_LOG_LEVEL, NULL);
 
-#if !defined(_WINDOWS) && (defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
+#if !defined(_WINDOWS) && (defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
 	if (SUCCEED != zbx_coredump_disable())
 	{
 		zabbix_log(LOG_LEVEL_CRIT, "cannot disable core dump, exiting...");
@@ -1053,7 +1053,7 @@ int	main(int argc, char **argv)
 			NULL != CONFIG_TLS_CERT_FILE || NULL != CONFIG_TLS_KEY_FILE ||
 			NULL != CONFIG_TLS_PSK_IDENTITY || NULL != CONFIG_TLS_PSK_FILE)
 	{
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		zbx_tls_validate_config();
 
 		if (ZBX_TCP_SEC_UNENCRYPTED != configured_tls_connect_mode)
@@ -1070,7 +1070,7 @@ int	main(int argc, char **argv)
 #endif
 	}
 
-#if defined(_WINDOWS) && (defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
+#if defined(_WINDOWS) && (defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
 	if (ZBX_TCP_SEC_UNENCRYPTED != configured_tls_connect_mode)
 	{
 		/* prepare to pass necessary TLS data to 'send_value' thread (to be started soon) */
@@ -1298,7 +1298,7 @@ exit:
 				" Use option -vv for more detailed output." : "");
 	}
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	if (ZBX_TCP_SEC_UNENCRYPTED != configured_tls_connect_mode)
 	{
 		zbx_tls_free();
diff --git a/src/zabbix_server/discoverer/discoverer.c b/src/zabbix_server/discoverer/discoverer.c
index 0829d19..a0aee5e 100644
--- a/src/zabbix_server/discoverer/discoverer.c
+++ b/src/zabbix_server/discoverer/discoverer.c
@@ -785,7 +785,7 @@ ZBX_THREAD_ENTRY(discoverer_thread, args)
 #define STAT_INTERVAL	5	/* if a process is busy and does not sleep then update status not faster than */
 				/* once in STAT_INTERVAL seconds */
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_init_child();
 #endif
 	zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num);
diff --git a/src/zabbix_server/escalator/escalator.c b/src/zabbix_server/escalator/escalator.c
index 6f2cd9e..7b49f6d 100644
--- a/src/zabbix_server/escalator/escalator.c
+++ b/src/zabbix_server/escalator/escalator.c
@@ -398,7 +398,7 @@ static int	get_dynamic_hostid(DB_EVENT *event, DC_HOST *host, char *error, size_
 			/* do not forget to update ZBX_IPMI_FIELDS_NUM if number of selected IPMI fields changes */
 			",h.ipmi_authtype,h.ipmi_privilege,h.ipmi_username,h.ipmi_password");
 #endif
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	offset += zbx_snprintf(sql + offset, sizeof(sql) - offset,
 			",h.tls_issuer,h.tls_subject,h.tls_psk_identity,h.tls_psk");
 #endif
@@ -479,7 +479,7 @@ static int	get_dynamic_hostid(DB_EVENT *event, DC_HOST *host, char *error, size_
 		strscpy(host->ipmi_password, row[6]);
 #endif
 		host->tls_connect = (unsigned char)atoi(row[2]);
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		strscpy(host->tls_issuer, row[3 + ZBX_IPMI_FIELDS_NUM]);
 		strscpy(host->tls_subject, row[4 + ZBX_IPMI_FIELDS_NUM]);
 		strscpy(host->tls_psk_identity, row[5 + ZBX_IPMI_FIELDS_NUM]);
@@ -529,7 +529,7 @@ static void	execute_commands(DB_EVENT *event, zbx_uint64_t actionid, zbx_uint64_
 			/* do not forget to update ZBX_IPMI_FIELDS_NUM if number of selected IPMI fields changes */
 			",h.ipmi_authtype,h.ipmi_privilege,h.ipmi_username,h.ipmi_password"
 #endif
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 			",h.tls_issuer,h.tls_subject,h.tls_psk_identity,h.tls_psk"
 #endif
 			);
@@ -549,7 +549,7 @@ static void	execute_commands(DB_EVENT *event, zbx_uint64_t actionid, zbx_uint64_
 #ifdef HAVE_OPENIPMI
 			",h.ipmi_authtype,h.ipmi_privilege,h.ipmi_username,h.ipmi_password"
 #endif
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 			",h.tls_issuer,h.tls_subject,h.tls_psk_identity,h.tls_psk"
 #endif
 			);
@@ -568,7 +568,7 @@ static void	execute_commands(DB_EVENT *event, zbx_uint64_t actionid, zbx_uint64_
 	zbx_strcpy_alloc(&buffer, &buffer_alloc, &buffer_offset,
 				",0,2,null,null");
 #endif
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_strcpy_alloc(&buffer, &buffer_alloc, &buffer_offset,
 				",null,null,null,null");
 #endif
@@ -629,7 +629,7 @@ static void	execute_commands(DB_EVENT *event, zbx_uint64_t actionid, zbx_uint64_
 				strscpy(host.ipmi_username, row[15]);
 				strscpy(host.ipmi_password, row[16]);
 #endif
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 				strscpy(host.tls_issuer, row[13 + ZBX_IPMI_FIELDS_NUM]);
 				strscpy(host.tls_subject, row[14 + ZBX_IPMI_FIELDS_NUM]);
 				strscpy(host.tls_psk_identity, row[15 + ZBX_IPMI_FIELDS_NUM]);
@@ -1758,7 +1758,7 @@ ZBX_THREAD_ENTRY(escalator_thread, args)
 #define STAT_INTERVAL	5	/* if a process is busy and does not sleep then update status not faster than */
 				/* once in STAT_INTERVAL seconds */
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_init_child();
 #endif
 	zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num);
diff --git a/src/zabbix_server/poller/checks_agent.c b/src/zabbix_server/poller/checks_agent.c
index afb03f8..2c36cd5 100644
--- a/src/zabbix_server/poller/checks_agent.c
+++ b/src/zabbix_server/poller/checks_agent.c
@@ -24,7 +24,7 @@
 
 #include "checks_agent.h"
 
-#if !(defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
+#if !(defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
 extern unsigned char	program_type;
 #endif
 
@@ -69,7 +69,7 @@ int	get_value_agent(DC_ITEM *item, AGENT_RESULT *result)
 			tls_arg1 = NULL;
 			tls_arg2 = NULL;
 			break;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		case ZBX_TCP_SEC_TLS_CERT:
 			tls_arg1 = item->host.tls_issuer;
 			tls_arg2 = item->host.tls_subject;
diff --git a/src/zabbix_server/poller/poller.c b/src/zabbix_server/poller/poller.c
index 630df97..ada6748 100644
--- a/src/zabbix_server/poller/poller.c
+++ b/src/zabbix_server/poller/poller.c
@@ -831,7 +831,7 @@ ZBX_THREAD_ENTRY(poller_thread, args)
 		zbx_init_snmp();
 #endif
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_init_child();
 #endif
 	zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num);
diff --git a/src/zabbix_server/proxypoller/proxypoller.c b/src/zabbix_server/proxypoller/proxypoller.c
index b4f137f..6561105 100644
--- a/src/zabbix_server/proxypoller/proxypoller.c
+++ b/src/zabbix_server/proxypoller/proxypoller.c
@@ -423,7 +423,7 @@ ZBX_THREAD_ENTRY(proxypoller_thread, args)
 #define STAT_INTERVAL	5	/* if a process is busy and does not sleep then update status not faster than */
 				/* once in STAT_INTERVAL seconds */
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_init_child();
 #endif
 	zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num);
diff --git a/src/zabbix_server/server.c b/src/zabbix_server/server.c
index 75ec389..6cc8ad2 100644
--- a/src/zabbix_server/server.c
+++ b/src/zabbix_server/server.c
@@ -227,7 +227,7 @@ char	*CONFIG_TLS_CA_FILE		= NULL;
 char	*CONFIG_TLS_CRL_FILE		= NULL;
 char	*CONFIG_TLS_CERT_FILE		= NULL;
 char	*CONFIG_TLS_KEY_FILE		= NULL;
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 /* the following TLS parameters are not used in server, they are defined for linking with tls.c */
 char	*CONFIG_TLS_CONNECT		= NULL;
 char	*CONFIG_TLS_ACCEPT		= NULL;
@@ -461,7 +461,7 @@ static void	zbx_validate_config(ZBX_TASK_EX *task)
 	if (SUCCEED != zbx_validate_log_parameters(task))
 		err = 1;
 
-#if !(defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
+#if !(defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL))
 	err |= (FAIL == check_cfg_feature_str("TLSCAFile", CONFIG_TLS_CA_FILE, "TLS support"));
 	err |= (FAIL == check_cfg_feature_str("TLSCRLFile", CONFIG_TLS_CRL_FILE, "TLS support"));
 	err |= (FAIL == check_cfg_feature_str("TLSCertFile", CONFIG_TLS_CERT_FILE, "TLS support"));
@@ -645,7 +645,7 @@ static void	zbx_load_config(ZBX_TASK_EX *task)
 	CONFIG_LOG_TYPE = zbx_get_log_type(CONFIG_LOG_TYPE_STR);
 
 	zbx_validate_config(task);
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_validate_config();
 #endif
 }
@@ -815,7 +815,7 @@ int	MAIN_ZABBIX_ENTRY(int flags)
 #else
 #	define IPV6_FEATURE_STATUS	" NO"
 #endif
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 #	define TLS_FEATURE_STATUS	"YES"
 #else
 #	define TLS_FEATURE_STATUS	" NO"
@@ -840,7 +840,7 @@ int	MAIN_ZABBIX_ENTRY(int flags)
 
 	zabbix_log(LOG_LEVEL_INFORMATION, "using configuration file: %s", CONFIG_FILE);
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	if (SUCCEED != zbx_coredump_disable())
 	{
 		zabbix_log(LOG_LEVEL_CRIT, "cannot disable core dump, exiting...");
@@ -913,7 +913,7 @@ int	MAIN_ZABBIX_ENTRY(int flags)
 		}
 	}
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_init_parent();
 #endif
 	zabbix_log(LOG_LEVEL_INFORMATION, "server #0 started [main process]");
diff --git a/src/zabbix_server/trapper/active.c b/src/zabbix_server/trapper/active.c
index d2daeb6..663a9e7 100644
--- a/src/zabbix_server/trapper/active.c
+++ b/src/zabbix_server/trapper/active.c
@@ -67,7 +67,7 @@ static int	get_hostid_by_host(const zbx_socket_t *sock, const char *host, const
 	host_esc = DBdyn_escape_string(host);
 
 	result =
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 		DBselect(
 			"select hostid,status,tls_accept,tls_issuer,tls_subject,tls_psk_identity"
 			" from hosts"
@@ -101,7 +101,7 @@ static int	get_hostid_by_host(const zbx_socket_t *sock, const char *host, const
 				goto done;
 			}
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 			if (ZBX_TCP_SEC_TLS_CERT == sock->connection_type)
 			{
 				zbx_tls_conn_attr_t	attr;
diff --git a/src/zabbix_server/trapper/trapper.c b/src/zabbix_server/trapper/trapper.c
index 3e3b8cb..87f63d7 100644
--- a/src/zabbix_server/trapper/trapper.c
+++ b/src/zabbix_server/trapper/trapper.c
@@ -694,7 +694,7 @@ ZBX_THREAD_ENTRY(trapper_thread, args)
 
 	memcpy(&s, (zbx_socket_t *)((zbx_thread_args_t *)args)->args, sizeof(zbx_socket_t));
 
-#if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+#if defined(HAVE_POLARSSL) || defined(HAVE_MBEDTLS21) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
 	zbx_tls_init_child();
 	find_psk_in_cache = DCget_psk_by_identity;
 #endif
