mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-18 19:04:38 +00:00
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
This commit is contained in:
commit
b30787ad24
13 changed files with 278 additions and 40 deletions
19
cmd/Kconfig
19
cmd/Kconfig
|
@ -2124,6 +2124,25 @@ config CMD_WGET
|
|||
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
|
||||
|
|
|
@ -7,3 +7,4 @@ CONFIG_NET_LWIP=y
|
|||
CONFIG_CMD_DNS=y
|
||||
CONFIG_CMD_WGET=y
|
||||
CONFIG_EFI_HTTP_BOOT=y
|
||||
CONFIG_WGET_HTTPS=y
|
||||
|
|
|
@ -681,8 +681,8 @@ UEFI variables. Booting according to these variables is possible via::
|
|||
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 @@ We need to preset the "httpserverip" environment variable to proceed the wget::
|
|||
|
||||
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
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -53,3 +53,6 @@ obj-y += \
|
|||
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
|
||||
|
|
|
@ -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 @@ struct altcp_tls_config {
|
|||
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_lower_recv_process(struct altcp_pcb *conn, altcp_mbed
|
|||
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 @@ altcp_mbedtls_lower_sent(void *arg, struct altcp_pcb *inner_conn, u16_t len)
|
|||
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 @@ altcp_mbedtls_lower_poll(void *arg, struct altcp_pcb *inner_conn)
|
|||
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 @@ altcp_mbedtls_setup(void *conf, struct altcp_pcb *conn, struct altcp_pcb *inner_
|
|||
/* 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 @@ altcp_tls_set_session(struct altcp_pcb *conn, struct altcp_tls_session *session)
|
|||
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 @@ altcp_tls_create_config(int is_server, u8_t cert_count, u8_t pkey_count, int hav
|
|||
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 @@ err_t altcp_tls_config_server_add_privkey_cert(struct altcp_tls_config *config,
|
|||
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 @@ altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_
|
|||
}
|
||||
|
||||
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 @@ altcp_tls_create_config_client_common(const u8_t *ca, size_t ca_len, int is_2way
|
|||
|
||||
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 @@ altcp_tls_create_config_client_2wayauth(const u8_t *ca, size_t ca_len, const u8_
|
|||
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 @@ altcp_tls_create_config_client_2wayauth(const u8_t *ca, size_t ca_len, const u8_
|
|||
}
|
||||
|
||||
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 @@ altcp_mbedtls_sndbuf(struct altcp_pcb *conn)
|
|||
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 @@ altcp_mbedtls_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t
|
|||
/* 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 @@ altcp_mbedtls_bio_send(void *ctx, const unsigned char *dataptr, size_t size)
|
|||
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;
|
||||
|
|
|
@ -1255,14 +1255,6 @@ tcp_output(struct tcp_pcb *pcb)
|
|||
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;
|
||||
|
|
|
@ -92,7 +92,7 @@ struct altcp_tls_config *altcp_tls_create_config_server_privkey_cert(const u8_t
|
|||
/** @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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -430,4 +430,16 @@ endif # SPL
|
|||
|
||||
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
|
||||
|
|
|
@ -26,6 +26,7 @@ mbedtls_lib_crypto-y := \
|
|||
$(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_x509-$(CONFIG_$(SPL_)X509_CERTIFICATE_PARSER_MBEDTLS) += \
|
|||
$(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 \
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -37,7 +37,7 @@ config PROT_UDP_LWIP
|
|||
|
||||
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
|
||||
|
|
|
@ -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 @@ struct wget_ctx {
|
|||
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;
|
||||
|
||||
p = strstr(url, "http://");
|
||||
if (!p) {
|
||||
log_err("only http:// is supported\n");
|
||||
if (!wget_validate_uri(url)) {
|
||||
log_err("Invalid URL. Use http(s)://\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
p += strlen("http://");
|
||||
*is_https = false;
|
||||
*port = HTTP_PORT_DEFAULT;
|
||||
prefix_len = strlen("http://");
|
||||
p = strstr(url, "http://");
|
||||
if (!p) {
|
||||
p = strstr(url, "https://");
|
||||
prefix_len = strlen("https://");
|
||||
*port = HTTPS_PORT_DEFAULT;
|
||||
*is_https = true;
|
||||
}
|
||||
|
||||
p += prefix_len;
|
||||
|
||||
/* Parse hostname */
|
||||
pp = strchr(p, ':');
|
||||
|
@ -67,9 +109,8 @@ static int parse_url(char *url, char *host, u16 *port, char **path)
|
|||
if (lport > 65535)
|
||||
return -EINVAL;
|
||||
*port = (u16)lport;
|
||||
} else {
|
||||
*port = HTTP_PORT_DEFAULT;
|
||||
}
|
||||
|
||||
if (*pp != '/')
|
||||
return -EINVAL;
|
||||
*path = pp;
|
||||
|
@ -210,12 +251,16 @@ static void httpc_result_cb(void *arg, httpc_result_t httpc_result,
|
|||
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 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri)
|
|||
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 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri)
|
|||
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 @@ bool wget_validate_uri(char *uri)
|
|||
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 @@ bool wget_validate_uri(char *uri)
|
|||
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;
|
||||
|
|
Loading…
Add table
Reference in a new issue