Add mbedtls to pico-sdk (#894)

* Add mbedtls as a submodule

Checked out on branch mbedtls-2.28

* Add mbedtls to pico-sdk

Link your code to pico_lwip_mbedtls and pico_mbedtls.
See tls_client example in pico-examples

Fixes https://github.com/raspberrypi/pico-sdk/issues/893
diff --git a/.gitmodules b/.gitmodules
index a37debe..3376914 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -7,3 +7,6 @@
 [submodule "lib/lwip"]
 	path = lib/lwip
 	url = https://github.com/lwip-tcpip/lwip.git
+[submodule "lib/mbedtls"]
+	path = lib/mbedtls
+	url = https://github.com/Mbed-TLS/mbedtls.git
diff --git a/lib/mbedtls b/lib/mbedtls
new file mode 160000
index 0000000..a77287f
--- /dev/null
+++ b/lib/mbedtls
@@ -0,0 +1 @@
+Subproject commit a77287f8fa6b76f74984121fdafc8563147435c8
diff --git a/src/rp2_common/CMakeLists.txt b/src/rp2_common/CMakeLists.txt
index 0d0f9b9..ff8df7c 100644
--- a/src/rp2_common/CMakeLists.txt
+++ b/src/rp2_common/CMakeLists.txt
@@ -61,6 +61,7 @@
     pico_add_subdirectory(cyw43_driver)
     pico_add_subdirectory(pico_lwip)
     pico_add_subdirectory(pico_cyw43_arch)
+    pico_add_subdirectory(pico_mbedtls)
 
     pico_add_subdirectory(pico_stdlib)
 
diff --git a/src/rp2_common/pico_mbedtls/CMakeLists.txt b/src/rp2_common/pico_mbedtls/CMakeLists.txt
new file mode 100644
index 0000000..0d9685b
--- /dev/null
+++ b/src/rp2_common/pico_mbedtls/CMakeLists.txt
@@ -0,0 +1,172 @@
+if (DEFINED ENV{PICO_MBEDTLS_PATH} AND (NOT PICO_MBEDTLS_PATH))
+    set(PICO_MBEDTLS_PATH $ENV{PICO_MBEDTLS_PATH})
+    message("Using PICO_MBEDTLS_PATH from environment ('${PICO_MBEDTLS_PATH}')")
+endif()
+
+set(MBEDTLS_TEST_PATH "library/aes.c")
+if (NOT PICO_MBEDTLS_PATH)
+    set(PICO_MBEDTLS_PATH ${PROJECT_SOURCE_DIR}/lib/mbedtls)
+elseif (NOT EXISTS ${PICO_MBEDTLS_PATH}/${MBEDTLS_TEST_PATH})
+    message(WARNING "PICO_MBEDTLS_PATH specified but content not present.")
+endif()
+
+if (EXISTS ${PICO_MBEDTLS_PATH}/${MBEDTLS_TEST_PATH})
+    message("mbedtls available at ${PICO_MBEDTLS_PATH}")
+
+    pico_register_common_scope_var(PICO_MBEDTLS_PATH)
+
+    set(src_crypto
+        aes.c
+        aesni.c
+        arc4.c
+        aria.c
+        asn1parse.c
+        asn1write.c
+        base64.c
+        bignum.c
+        blowfish.c
+        camellia.c
+        ccm.c
+        chacha20.c
+        chachapoly.c
+        cipher.c
+        cipher_wrap.c
+        constant_time.c
+        cmac.c
+        ctr_drbg.c
+        des.c
+        dhm.c
+        ecdh.c
+        ecdsa.c
+        ecjpake.c
+        ecp.c
+        ecp_curves.c
+        entropy.c
+        entropy_poll.c
+        error.c
+        gcm.c
+        havege.c
+        hkdf.c
+        hmac_drbg.c
+        md.c
+        md2.c
+        md4.c
+        md5.c
+        memory_buffer_alloc.c
+        mps_reader.c
+        mps_trace.c
+        nist_kw.c
+        oid.c
+        padlock.c
+        pem.c
+        pk.c
+        pk_wrap.c
+        pkcs12.c
+        pkcs5.c
+        pkparse.c
+        pkwrite.c
+        platform.c
+        platform_util.c
+        poly1305.c
+        psa_crypto.c
+        psa_crypto_aead.c
+        psa_crypto_cipher.c
+        psa_crypto_client.c
+        psa_crypto_driver_wrappers.c
+        psa_crypto_ecp.c
+        psa_crypto_hash.c
+        psa_crypto_mac.c
+        psa_crypto_rsa.c
+        psa_crypto_se.c
+        psa_crypto_slot_management.c
+        psa_crypto_storage.c
+        psa_its_file.c
+        ripemd160.c
+        rsa.c
+        rsa_internal.c
+        sha1.c
+        sha256.c
+        sha512.c
+        threading.c
+        timing.c
+        version.c
+        version_features.c
+        xtea.c
+    )
+    list(TRANSFORM src_crypto PREPEND ${PICO_MBEDTLS_PATH}/library/)
+    add_library(pico_mbedtls_crypto INTERFACE)
+    target_sources(pico_mbedtls_crypto INTERFACE ${src_crypto})
+
+    set(src_x509
+        certs.c
+        pkcs11.c
+        x509.c
+        x509_create.c
+        x509_crl.c
+        x509_crt.c
+        x509_csr.c
+        x509write_crt.c
+        x509write_csr.c
+    )
+    list(TRANSFORM src_x509 PREPEND ${PICO_MBEDTLS_PATH}/library/)
+    add_library(pico_mbedtls_x509 INTERFACE)
+    target_sources(pico_mbedtls_x509 INTERFACE ${src_x509})
+
+    set(src_tls
+        debug.c
+        net_sockets.c
+        ssl_cache.c
+        ssl_ciphersuites.c
+        ssl_cli.c
+        ssl_cookie.c
+        ssl_msg.c
+        ssl_srv.c
+        ssl_ticket.c
+        ssl_tls.c
+        ssl_tls13_keys.c
+    )
+    list(TRANSFORM src_tls PREPEND ${PICO_MBEDTLS_PATH}/library/)
+    add_library(pico_mbedtls_tls INTERFACE)
+    target_sources(pico_mbedtls_tls INTERFACE ${src_tls})
+
+    pico_add_impl_library(pico_mbedtls)
+    target_link_libraries(pico_mbedtls INTERFACE pico_mbedtls_crypto pico_mbedtls_x509 pico_mbedtls_tls)
+    if (DEFINED PICO_MBEDTLS_CONFIG_FILE)
+        target_compile_definitions(pico_mbedtls INTERFACE MBEDTLS_CONFIG_FILE="${PICO_MBEDTLS_CONFIG_FILE}")
+    else()
+        target_compile_definitions(pico_mbedtls INTERFACE MBEDTLS_CONFIG_FILE="mbedtls_config.h")
+    endif()
+    target_include_directories(pico_mbedtls INTERFACE ${PICO_MBEDTLS_PATH}/include/ ${PICO_MBEDTLS_PATH}/library/)
+
+    function(suppress_mbedtls_warnings)
+        set_source_files_properties(
+            ${PICO_MBEDTLS_PATH}/library/ecdsa.c
+            ${PICO_MBEDTLS_PATH}/library/ecp.c
+            ${PICO_MBEDTLS_PATH}/library/ecp_curves.c
+            ${PICO_MBEDTLS_PATH}/library/pk_wrap.c
+            ${PICO_MBEDTLS_PATH}/library/pkparse.c
+            ${PICO_MBEDTLS_PATH}/library/ssl_cli.c
+            PROPERTIES
+            COMPILE_OPTIONS "-Wno-cast-qual"
+        )
+        set_source_files_properties(
+            ${PICO_MBEDTLS_PATH}/library/psa_crypto_client.c
+            ${PICO_MBEDTLS_PATH}/library/psa_crypto_driver_wrappers.c
+            PROPERTIES
+            COMPILE_OPTIONS "-Wno-redundant-decls"
+        )
+        set_source_files_properties(
+            ${PICO_MBEDTLS_PATH}/library/x509_crt.c
+            PROPERTIES
+            COMPILE_OPTIONS "-Wno-cast-qual;-Wno-null-dereference"
+        )
+        set_source_files_properties(
+            ${PICO_MBEDTLS_PATH}/library/ssl_srv.c
+            ${PICO_MBEDTLS_PATH}/library/ssl_tls.c
+            PROPERTIES
+            COMPILE_OPTIONS "-Wno-null-dereference"
+        )
+    endfunction()
+
+    pico_promote_common_scope_vars()
+endif()
diff --git a/test/kitchen_sink/CMakeLists.txt b/test/kitchen_sink/CMakeLists.txt
index a201991..29b5fe4 100644
--- a/test/kitchen_sink/CMakeLists.txt
+++ b/test/kitchen_sink/CMakeLists.txt
@@ -142,4 +142,11 @@
     target_include_directories(kitchen_sink_lwip_background PRIVATE
             ${CMAKE_CURRENT_LIST_DIR})
 
+    target_link_libraries(kitchen_sink_lwip_poll
+        pico_lwip_mbedtls
+        pico_mbedtls)
+    target_link_libraries(kitchen_sink_lwip_background
+        pico_lwip_mbedtls
+        pico_mbedtls)
+    suppress_mbedtls_warnings()
 endif()
diff --git a/test/kitchen_sink/kitchen_sink.c b/test/kitchen_sink/kitchen_sink.c
index a49654d..8799065 100644
--- a/test/kitchen_sink/kitchen_sink.c
+++ b/test/kitchen_sink/kitchen_sink.c
@@ -82,7 +82,13 @@
 #include "hardware/structs/watchdog.h"
 #include "hardware/structs/xip_ctrl.h"
 #include "hardware/structs/xosc.h"
-        
+
+#if LIB_PICO_MBEDTLS
+#include "mbedtls/ssl.h"
+#include "lwip/altcp_tcp.h"
+#include "lwip/altcp_tls.h"
+#endif
+
 bi_decl(bi_block_device(
                            BINARY_INFO_MAKE_TAG('K', 'S'),
                            "foo",
diff --git a/test/kitchen_sink/mbedtls_config.h b/test/kitchen_sink/mbedtls_config.h
new file mode 100644
index 0000000..dae3395
--- /dev/null
+++ b/test/kitchen_sink/mbedtls_config.h
@@ -0,0 +1,63 @@
+/* Workaround for some mbedtls source files using INT_MAX without including limits.h */
+#include <limits.h>
+
+#define MBEDTLS_NO_PLATFORM_ENTROPY
+#define MBEDTLS_ENTROPY_HARDWARE_ALT
+
+#define MBEDTLS_SSL_OUT_CONTENT_LEN    2048
+
+#define MBEDTLS_ALLOW_PRIVATE_ACCESS
+#define MBEDTLS_HAVE_TIME
+
+#define MBEDTLS_CIPHER_MODE_CBC
+#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
+#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
+#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
+#define MBEDTLS_ECP_DP_BP256R1_ENABLED
+#define MBEDTLS_ECP_DP_BP384R1_ENABLED
+#define MBEDTLS_ECP_DP_BP512R1_ENABLED
+#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
+#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+#define MBEDTLS_PKCS1_V15
+#define MBEDTLS_SHA256_SMALLER
+#define MBEDTLS_SSL_SERVER_NAME_INDICATION
+#define MBEDTLS_AES_C
+#define MBEDTLS_ASN1_PARSE_C
+#define MBEDTLS_BIGNUM_C
+#define MBEDTLS_CIPHER_C
+#define MBEDTLS_CTR_DRBG_C
+#define MBEDTLS_ENTROPY_C
+#define MBEDTLS_ERROR_C
+#define MBEDTLS_MD_C
+#define MBEDTLS_MD5_C
+#define MBEDTLS_OID_C
+#define MBEDTLS_PKCS5_C
+#define MBEDTLS_PK_C
+#define MBEDTLS_PK_PARSE_C
+#define MBEDTLS_PLATFORM_C
+#define MBEDTLS_RSA_C
+#define MBEDTLS_SHA1_C
+#define MBEDTLS_SHA224_C
+#define MBEDTLS_SHA256_C
+#define MBEDTLS_SHA512_C
+#define MBEDTLS_SSL_CLI_C
+#define MBEDTLS_SSL_SRV_C
+#define MBEDTLS_SSL_TLS_C
+#define MBEDTLS_X509_CRT_PARSE_C
+#define MBEDTLS_X509_USE_C
+#define MBEDTLS_AES_FEWER_TABLES
+
+/* TLS 1.2 */
+#define MBEDTLS_SSL_PROTO_TLS1_2
+#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+#define MBEDTLS_GCM_C
+#define MBEDTLS_ECDH_C
+#define MBEDTLS_ECP_C
+#define MBEDTLS_ECDSA_C
+#define MBEDTLS_ASN1_WRITE_C
+