Merge patch series "Enable https for wget"
Ilias Apalodimas <ilias.apalodimas@linaro.org> says:
Hi all,
This is a respin of [1] adding https support to wget. In short
patch#1 enables the crypto algorithms we need in mbedTLS
patches#2, #3 enable anf fix the lwIP part we need
patch#4 is adding https:// parsing support in our wget
patch#5 is making https:// the default for QEMU lwip defconfig so
people can easily test
and finaly patch#6 updates our documentation
[1] https://lore.kernel.org/u-boot/20241024112449.1362319-1-ilias.apalodimas@linaro.org/
Link: https://lore.kernel.org/r/20241110083017.367565-1-ilias.apalodimas@linaro.org
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 6368336..b2d0348 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2124,6 +2124,25 @@
wget is a simple command to download kernel, or other files,
from a http server over TCP.
+config WGET_HTTPS
+ bool "wget https"
+ depends on CMD_WGET
+ depends on PROT_TCP_LWIP
+ depends on MBEDTLS_LIB
+ select SHA256
+ select RSA
+ select ASYMMETRIC_KEY_TYPE
+ select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+ select X509_CERTIFICATE_PARSER
+ select PKCS7_MESSAGE_PARSER
+ select MBEDTLS_LIB_CRYPTO
+ select MBEDTLS_LIB_TLS
+ select RSA_VERIFY_WITH_PKEY
+ select X509_CERTIFICATE_PARSER
+ select PKCS7_MESSAGE_PARSER
+ help
+ Enable TLS over http for wget.
+
endif # if CMD_NET
config CMD_PXE
diff --git a/configs/qemu_arm64_lwip_defconfig b/configs/qemu_arm64_lwip_defconfig
index d3d8ef1..754c770 100644
--- a/configs/qemu_arm64_lwip_defconfig
+++ b/configs/qemu_arm64_lwip_defconfig
@@ -7,3 +7,4 @@
CONFIG_CMD_DNS=y
CONFIG_CMD_WGET=y
CONFIG_EFI_HTTP_BOOT=y
+CONFIG_WGET_HTTPS=y
diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst
index 0760ca9..48d6110 100644
--- a/doc/develop/uefi/uefi.rst
+++ b/doc/develop/uefi/uefi.rst
@@ -681,8 +681,8 @@
As of U-Boot v2020.10 UEFI variables cannot be set at runtime. The U-Boot
command 'efidebug' can be used to set the variables.
-UEFI HTTP Boot
-~~~~~~~~~~~~~~
+UEFI HTTP Boot using the legacy TCP stack
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
HTTP Boot provides the capability for system deployment and configuration
over the network. HTTP Boot can be activated by specifying::
@@ -715,6 +715,47 @@
setenv httpserverip 192.168.1.1
+UEFI HTTP(s) Boot using lwIP
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Similar to the above U-Boot can do EFI HTTP boot using lwIP. If we combine this
+with Mbed TLS we can also download from https://
+
+HTTP(s) Boot can be activated by specifying::
+
+ CONFIG_EFI_HTTP_BOOT
+ CONFIG_NET_LWIP
+ CONFIG_WGET_HTTPS
+
+For QEMU targets there's a Kconfig that supports this by default::
+
+ make qemu_arm64_lwip_defconfig
+
+The commands and functionality are similar to the legacy stack, with the notable
+exception of not having to define an "httpserverip" if you are trying to resolve
+an IP. However, lwIP code doesn't yet support redirects::
+
+ => efidebug boot add -u 1 netinst https://cdimage.debian.org/cdimage/weekly-builds/arm64/iso-cd/debian-testing-arm64-netinst.iso
+ => dhcp
+ DHCP client bound to address 10.0.2.15 (3 ms)
+ => efidebug boot order 1
+ => bootefi bootmgr
+
+ HTTP server error 302
+ Loading Boot0001 'netinst' failed
+ EFI boot manager: Cannot load any image
+
+If the url you specified isn't a redirect::
+
+ => efidebug boot add -u 1 netinst https://download.rockylinux.org/pub/rocky/9/isos/aarch64/Rocky-9.4-aarch64-minimal.iso
+ => dhcp
+ => bootefi bootmgr
+ #######################################
+
+If the downloaded file extension is .iso or .img file, efibootmgr tries to
+mount the image and boot with the default file(e.g. EFI/BOOT/BOOTAA64.EFI).
+If the downloaded file is PE-COFF image, load the downloaded file and
+start it.
+
Executing the built in hello world application
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/lib/lwip/Makefile b/lib/lwip/Makefile
index dfcd700..19e5c68 100644
--- a/lib/lwip/Makefile
+++ b/lib/lwip/Makefile
@@ -53,3 +53,6 @@
lwip/src/core/timeouts.o \
lwip/src/core/udp.o \
lwip/src/netif/ethernet.o
+
+obj-$(CONFIG_MBEDTLS_LIB_TLS) += lwip/src/apps/altcp_tls/altcp_tls_mbedtls.o \
+ lwip/src/apps/altcp_tls/altcp_tls_mbedtls_mem.o
diff --git a/lib/lwip/lwip/src/apps/altcp_tls/altcp_tls_mbedtls.c b/lib/lwip/lwip/src/apps/altcp_tls/altcp_tls_mbedtls.c
index a8c2fc2..6643b05 100644
--- a/lib/lwip/lwip/src/apps/altcp_tls/altcp_tls_mbedtls.c
+++ b/lib/lwip/lwip/src/apps/altcp_tls/altcp_tls_mbedtls.c
@@ -70,7 +70,6 @@
/* @todo: which includes are really needed? */
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
-#include "mbedtls/certs.h"
#include "mbedtls/x509.h"
#include "mbedtls/ssl.h"
#include "mbedtls/net_sockets.h"
@@ -81,8 +80,6 @@
#include "mbedtls/ssl_cache.h"
#include "mbedtls/ssl_ticket.h"
-#include "mbedtls/ssl_internal.h" /* to call mbedtls_flush_output after ERR_MEM */
-
#include <string.h>
#ifndef ALTCP_MBEDTLS_ENTROPY_PTR
@@ -109,6 +106,7 @@
u8_t pkey_count;
u8_t pkey_max;
mbedtls_x509_crt *ca;
+ char host[256];
#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_USE_SESSION_CACHE
/** Inter-connection cache for fast connection startup */
struct mbedtls_ssl_cache_context cache;
@@ -132,6 +130,16 @@
static err_t altcp_mbedtls_handle_rx_appldata(struct altcp_pcb *conn, altcp_mbedtls_state_t *state);
static int altcp_mbedtls_bio_send(void *ctx, const unsigned char *dataptr, size_t size);
+static void
+altcp_mbedtls_flush_output(altcp_mbedtls_state_t *state)
+{
+ if (state->ssl_context.MBEDTLS_PRIVATE(out_left) != 0) {
+ int flushed = mbedtls_ssl_send_alert_message(&state->ssl_context, 0, 0);
+ if (flushed) {
+ LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_send_alert_message failed: %d\n", flushed));
+ }
+ }
+}
/* callback functions from inner/lower connection: */
@@ -524,14 +532,14 @@
LWIP_ASSERT("state", state != NULL);
LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn);
/* calculate TLS overhead part to not send it to application */
- overhead = state->overhead_bytes_adjust + state->ssl_context.out_left;
+ overhead = state->overhead_bytes_adjust + state->ssl_context.MBEDTLS_PRIVATE(out_left);
if ((unsigned)overhead > len) {
overhead = len;
}
/* remove ACKed bytes from overhead adjust counter */
state->overhead_bytes_adjust -= len;
/* try to send more if we failed before (may increase overhead adjust counter) */
- mbedtls_ssl_flush_output(&state->ssl_context);
+ altcp_mbedtls_flush_output(state);
/* remove calculated overhead from ACKed bytes len */
app_len = len - (u16_t)overhead;
/* update application write counter and inform application */
@@ -559,7 +567,7 @@
if (conn->state) {
altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
/* try to send more if we failed before */
- mbedtls_ssl_flush_output(&state->ssl_context);
+ altcp_mbedtls_flush_output(state);
if (altcp_mbedtls_handle_rx_appldata(conn, state) == ERR_ABRT) {
return ERR_ABRT;
}
@@ -635,6 +643,7 @@
/* tell mbedtls about our I/O functions */
mbedtls_ssl_set_bio(&state->ssl_context, conn, altcp_mbedtls_bio_send, altcp_mbedtls_bio_recv, NULL);
+ mbedtls_ssl_set_hostname(&state->ssl_context, config->host);
altcp_mbedtls_setup_callbacks(conn, inner_conn);
conn->inner_conn = inner_conn;
conn->fns = &altcp_mbedtls_functions;
@@ -683,7 +692,7 @@
if (session && conn && conn->state) {
altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
int ret = -1;
- if (session->data.start)
+ if (session->data.MBEDTLS_PRIVATE(start))
ret = mbedtls_ssl_set_session(&state->ssl_context, &session->data);
return ret < 0 ? ERR_VAL : ERR_OK;
}
@@ -776,7 +785,7 @@
struct altcp_tls_config *conf;
mbedtls_x509_crt *mem;
- if (TCP_WND < MBEDTLS_SSL_MAX_CONTENT_LEN) {
+ if (TCP_WND < MBEDTLS_SSL_IN_CONTENT_LEN || TCP_WND < MBEDTLS_SSL_OUT_CONTENT_LEN) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG|LWIP_DBG_LEVEL_SERIOUS,
("altcp_tls: TCP_WND is smaller than the RX decrypion buffer, connection RX might stall!\n"));
}
@@ -900,7 +909,7 @@
return ERR_VAL;
}
- ret = mbedtls_pk_parse_key(pkey, (const unsigned char *) privkey, privkey_len, privkey_pass, privkey_pass_len);
+ ret = mbedtls_pk_parse_key(pkey, (const unsigned char *) privkey, privkey_len, privkey_pass, privkey_pass_len, mbedtls_ctr_drbg_random, &altcp_tls_entropy_rng->ctr_drbg);
if (ret != 0) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_public_key failed: %d\n", ret));
mbedtls_x509_crt_free(srvcert);
@@ -944,7 +953,7 @@
}
static struct altcp_tls_config *
-altcp_tls_create_config_client_common(const u8_t *ca, size_t ca_len, int is_2wayauth)
+altcp_tls_create_config_client_common(const u8_t *ca, size_t ca_len, int is_2wayauth, char *host)
{
int ret;
struct altcp_tls_config *conf = altcp_tls_create_config(0, (is_2wayauth) ? 1 : 0, (is_2wayauth) ? 1 : 0, ca != NULL);
@@ -966,13 +975,15 @@
mbedtls_ssl_conf_ca_chain(&conf->conf, conf->ca, NULL);
}
+ strlcpy(conf->host, host, sizeof(conf->host));
+
return conf;
}
struct altcp_tls_config *
-altcp_tls_create_config_client(const u8_t *ca, size_t ca_len)
+altcp_tls_create_config_client(const u8_t *ca, size_t ca_len, char *host)
{
- return altcp_tls_create_config_client_common(ca, ca_len, 0);
+ return altcp_tls_create_config_client_common(ca, ca_len, 0, host);
}
struct altcp_tls_config *
@@ -988,7 +999,7 @@
return NULL;
}
- conf = altcp_tls_create_config_client_common(ca, ca_len, 1);
+ conf = altcp_tls_create_config_client_common(ca, ca_len, 1, NULL);
if (conf == NULL) {
return NULL;
}
@@ -1003,7 +1014,7 @@
}
mbedtls_pk_init(conf->pkey);
- ret = mbedtls_pk_parse_key(conf->pkey, privkey, privkey_len, privkey_pass, privkey_pass_len);
+ ret = mbedtls_pk_parse_key(conf->pkey, privkey, privkey_len, privkey_pass, privkey_pass_len, mbedtls_ctr_drbg_random, &altcp_tls_entropy_rng->ctr_drbg);
if (ret != 0) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_key failed: %d 0x%x\n", ret, -1*ret));
altcp_tls_free_config(conf);
@@ -1189,7 +1200,7 @@
size_t ret;
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
/* @todo: adjust ssl_added to real value related to negotiated cipher */
- size_t max_frag_len = mbedtls_ssl_get_max_frag_len(&state->ssl_context);
+ size_t max_frag_len = mbedtls_ssl_get_max_in_record_payload(&state->ssl_context);
max_len = LWIP_MIN(max_frag_len, max_len);
#endif
/* Adjust sndbuf of inner_conn with what added by SSL */
@@ -1232,9 +1243,9 @@
/* HACK: if there is something left to send, try to flush it and only
allow sending more if this succeeded (this is a hack because neither
returning 0 nor MBEDTLS_ERR_SSL_WANT_WRITE worked for me) */
- if (state->ssl_context.out_left) {
- mbedtls_ssl_flush_output(&state->ssl_context);
- if (state->ssl_context.out_left) {
+ if (state->ssl_context.MBEDTLS_PRIVATE(out_left)) {
+ altcp_mbedtls_flush_output(state);
+ if (state->ssl_context.MBEDTLS_PRIVATE(out_left)) {
return ERR_MEM;
}
}
@@ -1284,6 +1295,8 @@
while (size_left) {
u16_t write_len = (u16_t)LWIP_MIN(size_left, 0xFFFF);
err_t err = altcp_write(conn->inner_conn, (const void *)dataptr, write_len, apiflags);
+ /* try to send data... */
+ altcp_output(conn->inner_conn);
if (err == ERR_OK) {
written += write_len;
size_left -= write_len;
diff --git a/lib/lwip/lwip/src/core/tcp_out.c b/lib/lwip/lwip/src/core/tcp_out.c
index 64579ee5..6dbc5f9 100644
--- a/lib/lwip/lwip/src/core/tcp_out.c
+++ b/lib/lwip/lwip/src/core/tcp_out.c
@@ -1255,14 +1255,6 @@
LWIP_ASSERT("don't call tcp_output for listen-pcbs",
pcb->state != LISTEN);
- /* First, check if we are invoked by the TCP input processing
- code. If so, we do not output anything. Instead, we rely on the
- input processing code to call us when input processing is done
- with. */
- if (tcp_input_pcb == pcb) {
- return ERR_OK;
- }
-
wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
seg = pcb->unsent;
diff --git a/lib/lwip/lwip/src/include/lwip/altcp_tls.h b/lib/lwip/lwip/src/include/lwip/altcp_tls.h
index fcb784d..fb06182 100644
--- a/lib/lwip/lwip/src/include/lwip/altcp_tls.h
+++ b/lib/lwip/lwip/src/include/lwip/altcp_tls.h
@@ -92,7 +92,7 @@
/** @ingroup altcp_tls
* Create an ALTCP_TLS client configuration handle
*/
-struct altcp_tls_config *altcp_tls_create_config_client(const u8_t *cert, size_t cert_len);
+struct altcp_tls_config *altcp_tls_create_config_client(const u8_t *cert, size_t cert_len, char *host);
/** @ingroup altcp_tls
* Create an ALTCP_TLS client configuration handle with two-way server/client authentication
diff --git a/lib/lwip/u-boot/lwipopts.h b/lib/lwip/u-boot/lwipopts.h
index 9d61862..88d6faf 100644
--- a/lib/lwip/u-boot/lwipopts.h
+++ b/lib/lwip/u-boot/lwipopts.h
@@ -154,4 +154,10 @@
#define MEMP_MEM_INIT 1
#define MEM_LIBC_MALLOC 1
+#if defined(CONFIG_MBEDTLS_LIB_TLS)
+#define LWIP_ALTCP 1
+#define LWIP_ALTCP_TLS 1
+#define LWIP_ALTCP_TLS_MBEDTLS 1
+#endif
+
#endif /* LWIP_UBOOT_LWIPOPTS_H */
diff --git a/lib/mbedtls/Kconfig b/lib/mbedtls/Kconfig
index d71adc3..78167ff 100644
--- a/lib/mbedtls/Kconfig
+++ b/lib/mbedtls/Kconfig
@@ -430,4 +430,16 @@
endif # MBEDTLS_LIB_X509
+config MBEDTLS_LIB_TLS
+ bool "MbedTLS TLS library"
+ depends on RSA_PUBLIC_KEY_PARSER_MBEDTLS
+ depends on X509_CERTIFICATE_PARSER_MBEDTLS
+ depends on ASYMMETRIC_PUBLIC_KEY_MBEDTLS
+ depends on ASN1_DECODER_MBEDTLS
+ depends on ASYMMETRIC_PUBLIC_KEY_MBEDTLS
+ depends on MBEDTLS_LIB_CRYPTO
+ help
+ Enable MbedTLS TLS library. Required for HTTPs support
+ in wget
+
endif # MBEDTLS_LIB
diff --git a/lib/mbedtls/Makefile b/lib/mbedtls/Makefile
index 83cb3c2..ce0a61e 100644
--- a/lib/mbedtls/Makefile
+++ b/lib/mbedtls/Makefile
@@ -26,6 +26,7 @@
$(MBEDTLS_LIB_DIR)/platform_util.o \
$(MBEDTLS_LIB_DIR)/constant_time.o \
$(MBEDTLS_LIB_DIR)/md.o
+
mbedtls_lib_crypto-$(CONFIG_$(SPL_)MD5_MBEDTLS) += $(MBEDTLS_LIB_DIR)/md5.o
mbedtls_lib_crypto-$(CONFIG_$(SPL_)SHA1_MBEDTLS) += $(MBEDTLS_LIB_DIR)/sha1.o
mbedtls_lib_crypto-$(CONFIG_$(SPL_)SHA256_MBEDTLS) += \
@@ -54,3 +55,33 @@
$(MBEDTLS_LIB_DIR)/x509_crt.o
mbedtls_lib_x509-$(CONFIG_$(SPL_)PKCS7_MESSAGE_PARSER_MBEDTLS) += \
$(MBEDTLS_LIB_DIR)/pkcs7.o
+
+#mbedTLS TLS support
+obj-$(CONFIG_MBEDTLS_LIB_TLS) += mbedtls_lib_tls.o
+mbedtls_lib_tls-y := \
+ $(MBEDTLS_LIB_DIR)/mps_reader.o \
+ $(MBEDTLS_LIB_DIR)/mps_trace.o \
+ $(MBEDTLS_LIB_DIR)/net_sockets.o \
+ $(MBEDTLS_LIB_DIR)/pk_ecc.o \
+ $(MBEDTLS_LIB_DIR)/ssl_cache.o \
+ $(MBEDTLS_LIB_DIR)/ssl_ciphersuites.o \
+ $(MBEDTLS_LIB_DIR)/ssl_client.o \
+ $(MBEDTLS_LIB_DIR)/ssl_cookie.o \
+ $(MBEDTLS_LIB_DIR)/ssl_debug_helpers_generated.o \
+ $(MBEDTLS_LIB_DIR)/ssl_msg.o \
+ $(MBEDTLS_LIB_DIR)/ssl_ticket.o \
+ $(MBEDTLS_LIB_DIR)/ssl_tls.o \
+ $(MBEDTLS_LIB_DIR)/ssl_tls12_client.o \
+ $(MBEDTLS_LIB_DIR)/hmac_drbg.o \
+ $(MBEDTLS_LIB_DIR)/ctr_drbg.o \
+ $(MBEDTLS_LIB_DIR)/entropy.o \
+ $(MBEDTLS_LIB_DIR)/entropy_poll.o \
+ $(MBEDTLS_LIB_DIR)/aes.o \
+ $(MBEDTLS_LIB_DIR)/cipher.o \
+ $(MBEDTLS_LIB_DIR)/cipher_wrap.o \
+ $(MBEDTLS_LIB_DIR)/ecdh.o \
+ $(MBEDTLS_LIB_DIR)/ecdsa.o \
+ $(MBEDTLS_LIB_DIR)/ecp.o \
+ $(MBEDTLS_LIB_DIR)/ecp_curves.o \
+ $(MBEDTLS_LIB_DIR)/ecp_curves_new.o \
+ $(MBEDTLS_LIB_DIR)/gcm.o \
diff --git a/lib/mbedtls/mbedtls_def_config.h b/lib/mbedtls/mbedtls_def_config.h
index 1af911c..d27f017 100644
--- a/lib/mbedtls/mbedtls_def_config.h
+++ b/lib/mbedtls/mbedtls_def_config.h
@@ -87,4 +87,56 @@
#endif /* #if defined CONFIG_MBEDTLS_LIB_X509 */
+#if IS_ENABLED(CONFIG_MBEDTLS_LIB_TLS)
+#include "rtc.h"
+
+/* Generic options */
+#define MBEDTLS_ENTROPY_HARDWARE_ALT
+#define MBEDTLS_HAVE_TIME
+#define MBEDTLS_PLATFORM_MS_TIME_ALT
+#define MBEDTLS_PLATFORM_TIME_MACRO rtc_mktime
+#define MBEDTLS_PLATFORM_C
+#define MBEDTLS_SSL_CLI_C
+#define MBEDTLS_SSL_TLS_C
+#define MBEDTLS_CIPHER_C
+#define MBEDTLS_MD_C
+#define MBEDTLS_CTR_DRBG_C
+#define MBEDTLS_AES_C
+#define MBEDTLS_ENTROPY_C
+#define MBEDTLS_NO_PLATFORM_ENTROPY
+#define MBEDTLS_SSL_PROTO_TLS1_2
+#define MBEDTLS_SSL_SERVER_NAME_INDICATION
+#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+
+/* RSA */
+#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+#define MBEDTLS_GCM_C
+
+/* ECDSA */
+#define MBEDTLS_ECDSA_C
+#define MBEDTLS_ECDH_C
+#define MBEDTLS_ECDSA_DETERMINISTIC
+#define MBEDTLS_HMAC_DRBG_C
+#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+#define MBEDTLS_CAN_ECDH
+#define MBEDTLS_PK_CAN_ECDSA_SIGN
+#define MBEDTLS_ECP_C
+#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
+#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
+
+#endif /* #if defined CONFIG_MBEDTLS_LIB_TLS */
+
#endif /* #if defined CONFIG_MBEDTLS_LIB */
diff --git a/net/lwip/Kconfig b/net/lwip/Kconfig
index 8a67de4..a9ae9bf 100644
--- a/net/lwip/Kconfig
+++ b/net/lwip/Kconfig
@@ -37,7 +37,7 @@
config LWIP_TCP_WND
int "Value of TCP_WND"
- default 8000 if ARCH_QEMU
+ default 32768 if ARCH_QEMU
default 3000000
help
Default value for TCP_WND in the lwIP configuration
diff --git a/net/lwip/wget.c b/net/lwip/wget.c
index b495ebd..ba85798 100644
--- a/net/lwip/wget.c
+++ b/net/lwip/wget.c
@@ -7,13 +7,17 @@
#include <efi_loader.h>
#include <image.h>
#include <lwip/apps/http_client.h>
+#include "lwip/altcp_tls.h"
#include <lwip/timeouts.h>
+#include <rng.h>
#include <mapmem.h>
#include <net.h>
#include <time.h>
+#include <dm/uclass.h>
#define SERVER_NAME_SIZE 200
#define HTTP_PORT_DEFAULT 80
+#define HTTPS_PORT_DEFAULT 443
#define PROGRESS_PRINT_STEP_BYTES (100 * 1024)
enum done_state {
@@ -32,18 +36,56 @@
enum done_state done;
};
-static int parse_url(char *url, char *host, u16 *port, char **path)
+bool wget_validate_uri(char *uri);
+
+int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len,
+ size_t *olen)
+{
+ struct udevice *dev;
+ u64 rng = 0;
+ int ret;
+
+ *olen = 0;
+
+ ret = uclass_get_device(UCLASS_RNG, 0, &dev);
+ if (ret) {
+ log_err("Failed to get an rng: %d\n", ret);
+ return ret;
+ }
+ ret = dm_rng_read(dev, &rng, sizeof(rng));
+ if (ret)
+ return ret;
+
+ memcpy(output, &rng, len);
+ *olen = sizeof(rng);
+
+ return 0;
+}
+
+static int parse_url(char *url, char *host, u16 *port, char **path,
+ bool *is_https)
{
char *p, *pp;
long lport;
+ size_t prefix_len = 0;
+ if (!wget_validate_uri(url)) {
+ log_err("Invalid URL. Use http(s)://\n");
+ return -EINVAL;
+ }
+
+ *is_https = false;
+ *port = HTTP_PORT_DEFAULT;
+ prefix_len = strlen("http://");
p = strstr(url, "http://");
if (!p) {
- log_err("only http:// is supported\n");
- return -EINVAL;
+ p = strstr(url, "https://");
+ prefix_len = strlen("https://");
+ *port = HTTPS_PORT_DEFAULT;
+ *is_https = true;
}
- p += strlen("http://");
+ p += prefix_len;
/* Parse hostname */
pp = strchr(p, ':');
@@ -67,9 +109,8 @@
if (lport > 65535)
return -EINVAL;
*port = (u16)lport;
- } else {
- *port = HTTP_PORT_DEFAULT;
}
+
if (*pp != '/')
return -EINVAL;
*path = pp;
@@ -210,12 +251,16 @@
static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri)
{
char server_name[SERVER_NAME_SIZE];
+#if defined CONFIG_WGET_HTTPS
+ altcp_allocator_t tls_allocator;
+#endif
httpc_connection_t conn;
httpc_state_t *state;
struct netif *netif;
struct wget_ctx ctx;
char *path;
u16 port;
+ bool is_https;
ctx.daddr = dst_addr;
ctx.saved_daddr = dst_addr;
@@ -224,7 +269,7 @@
ctx.prevsize = 0;
ctx.start_time = 0;
- if (parse_url(uri, server_name, &port, &path))
+ if (parse_url(uri, server_name, &port, &path, &is_https))
return CMD_RET_USAGE;
netif = net_lwip_new_netif(udev);
@@ -232,6 +277,22 @@
return -1;
memset(&conn, 0, sizeof(conn));
+#if defined CONFIG_WGET_HTTPS
+ if (is_https) {
+ tls_allocator.alloc = &altcp_tls_alloc;
+ tls_allocator.arg =
+ altcp_tls_create_config_client(NULL, 0, server_name);
+
+ if (!tls_allocator.arg) {
+ log_err("error: Cannot create a TLS connection\n");
+ net_lwip_remove_netif(netif);
+ return -1;
+ }
+
+ conn.altcp_allocator = &tls_allocator;
+ }
+#endif
+
conn.result_fn = httpc_result_cb;
ctx.path = path;
if (httpc_get_file_dns(server_name, port, path, &conn, httpc_recv_cb,
@@ -316,6 +377,7 @@
char c;
bool ret = true;
char *str_copy, *s, *authority;
+ size_t prefix_len = 0;
for (c = 0x1; c < 0x21; c++) {
if (strchr(uri, c)) {
@@ -323,15 +385,21 @@
return false;
}
}
+
if (strchr(uri, 0x7f)) {
log_err("invalid character is used\n");
return false;
}
- if (strncmp(uri, "http://", 7)) {
- log_err("only http:// is supported\n");
+ if (!strncmp(uri, "http://", strlen("http://"))) {
+ prefix_len = strlen("http://");
+ } else if (!strncmp(uri, "https://", strlen("https://"))) {
+ prefix_len = strlen("https://");
+ } else {
+ log_err("only http(s):// is supported\n");
return false;
}
+
str_copy = strdup(uri);
if (!str_copy)
return false;