mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-25 14:56:03 +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,
|
wget is a simple command to download kernel, or other files,
|
||||||
from a http server over TCP.
|
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
|
endif # if CMD_NET
|
||||||
|
|
||||||
config CMD_PXE
|
config CMD_PXE
|
||||||
|
|
|
@ -7,3 +7,4 @@ CONFIG_NET_LWIP=y
|
||||||
CONFIG_CMD_DNS=y
|
CONFIG_CMD_DNS=y
|
||||||
CONFIG_CMD_WGET=y
|
CONFIG_CMD_WGET=y
|
||||||
CONFIG_EFI_HTTP_BOOT=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
|
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.
|
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
|
HTTP Boot provides the capability for system deployment and configuration
|
||||||
over the network. HTTP Boot can be activated by specifying::
|
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
|
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
|
Executing the built in hello world application
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -53,3 +53,6 @@ obj-y += \
|
||||||
lwip/src/core/timeouts.o \
|
lwip/src/core/timeouts.o \
|
||||||
lwip/src/core/udp.o \
|
lwip/src/core/udp.o \
|
||||||
lwip/src/netif/ethernet.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? */
|
/* @todo: which includes are really needed? */
|
||||||
#include "mbedtls/entropy.h"
|
#include "mbedtls/entropy.h"
|
||||||
#include "mbedtls/ctr_drbg.h"
|
#include "mbedtls/ctr_drbg.h"
|
||||||
#include "mbedtls/certs.h"
|
|
||||||
#include "mbedtls/x509.h"
|
#include "mbedtls/x509.h"
|
||||||
#include "mbedtls/ssl.h"
|
#include "mbedtls/ssl.h"
|
||||||
#include "mbedtls/net_sockets.h"
|
#include "mbedtls/net_sockets.h"
|
||||||
|
@ -81,8 +80,6 @@
|
||||||
#include "mbedtls/ssl_cache.h"
|
#include "mbedtls/ssl_cache.h"
|
||||||
#include "mbedtls/ssl_ticket.h"
|
#include "mbedtls/ssl_ticket.h"
|
||||||
|
|
||||||
#include "mbedtls/ssl_internal.h" /* to call mbedtls_flush_output after ERR_MEM */
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifndef ALTCP_MBEDTLS_ENTROPY_PTR
|
#ifndef ALTCP_MBEDTLS_ENTROPY_PTR
|
||||||
|
@ -109,6 +106,7 @@ struct altcp_tls_config {
|
||||||
u8_t pkey_count;
|
u8_t pkey_count;
|
||||||
u8_t pkey_max;
|
u8_t pkey_max;
|
||||||
mbedtls_x509_crt *ca;
|
mbedtls_x509_crt *ca;
|
||||||
|
char host[256];
|
||||||
#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_USE_SESSION_CACHE
|
#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_USE_SESSION_CACHE
|
||||||
/** Inter-connection cache for fast connection startup */
|
/** Inter-connection cache for fast connection startup */
|
||||||
struct mbedtls_ssl_cache_context cache;
|
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 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 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: */
|
/* 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("state", state != NULL);
|
||||||
LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn);
|
LWIP_ASSERT("pcb mismatch", conn->inner_conn == inner_conn);
|
||||||
/* calculate TLS overhead part to not send it to application */
|
/* 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) {
|
if ((unsigned)overhead > len) {
|
||||||
overhead = len;
|
overhead = len;
|
||||||
}
|
}
|
||||||
/* remove ACKed bytes from overhead adjust counter */
|
/* remove ACKed bytes from overhead adjust counter */
|
||||||
state->overhead_bytes_adjust -= len;
|
state->overhead_bytes_adjust -= len;
|
||||||
/* try to send more if we failed before (may increase overhead adjust counter) */
|
/* 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 */
|
/* remove calculated overhead from ACKed bytes len */
|
||||||
app_len = len - (u16_t)overhead;
|
app_len = len - (u16_t)overhead;
|
||||||
/* update application write counter and inform application */
|
/* 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) {
|
if (conn->state) {
|
||||||
altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
|
altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
|
||||||
/* try to send more if we failed before */
|
/* 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) {
|
if (altcp_mbedtls_handle_rx_appldata(conn, state) == ERR_ABRT) {
|
||||||
return 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 */
|
/* 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_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);
|
altcp_mbedtls_setup_callbacks(conn, inner_conn);
|
||||||
conn->inner_conn = inner_conn;
|
conn->inner_conn = inner_conn;
|
||||||
conn->fns = &altcp_mbedtls_functions;
|
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) {
|
if (session && conn && conn->state) {
|
||||||
altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
|
altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
if (session->data.start)
|
if (session->data.MBEDTLS_PRIVATE(start))
|
||||||
ret = mbedtls_ssl_set_session(&state->ssl_context, &session->data);
|
ret = mbedtls_ssl_set_session(&state->ssl_context, &session->data);
|
||||||
return ret < 0 ? ERR_VAL : ERR_OK;
|
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;
|
struct altcp_tls_config *conf;
|
||||||
mbedtls_x509_crt *mem;
|
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,
|
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"));
|
("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;
|
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) {
|
if (ret != 0) {
|
||||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_public_key failed: %d\n", ret));
|
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_public_key failed: %d\n", ret));
|
||||||
mbedtls_x509_crt_free(srvcert);
|
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 *
|
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;
|
int ret;
|
||||||
struct altcp_tls_config *conf = altcp_tls_create_config(0, (is_2wayauth) ? 1 : 0, (is_2wayauth) ? 1 : 0, ca != NULL);
|
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);
|
mbedtls_ssl_conf_ca_chain(&conf->conf, conf->ca, NULL);
|
||||||
}
|
}
|
||||||
|
strlcpy(conf->host, host, sizeof(conf->host));
|
||||||
|
|
||||||
return conf;
|
return conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct altcp_tls_config *
|
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 *
|
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;
|
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) {
|
if (conf == NULL) {
|
||||||
return 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);
|
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) {
|
if (ret != 0) {
|
||||||
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_key failed: %d 0x%x\n", ret, -1*ret));
|
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_key failed: %d 0x%x\n", ret, -1*ret));
|
||||||
altcp_tls_free_config(conf);
|
altcp_tls_free_config(conf);
|
||||||
|
@ -1189,7 +1200,7 @@ altcp_mbedtls_sndbuf(struct altcp_pcb *conn)
|
||||||
size_t ret;
|
size_t ret;
|
||||||
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
|
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
|
||||||
/* @todo: adjust ssl_added to real value related to negotiated cipher */
|
/* @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);
|
max_len = LWIP_MIN(max_frag_len, max_len);
|
||||||
#endif
|
#endif
|
||||||
/* Adjust sndbuf of inner_conn with what added by SSL */
|
/* 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
|
/* 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
|
allow sending more if this succeeded (this is a hack because neither
|
||||||
returning 0 nor MBEDTLS_ERR_SSL_WANT_WRITE worked for me) */
|
returning 0 nor MBEDTLS_ERR_SSL_WANT_WRITE worked for me) */
|
||||||
if (state->ssl_context.out_left) {
|
if (state->ssl_context.MBEDTLS_PRIVATE(out_left)) {
|
||||||
mbedtls_ssl_flush_output(&state->ssl_context);
|
altcp_mbedtls_flush_output(state);
|
||||||
if (state->ssl_context.out_left) {
|
if (state->ssl_context.MBEDTLS_PRIVATE(out_left)) {
|
||||||
return ERR_MEM;
|
return ERR_MEM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1284,6 +1295,8 @@ altcp_mbedtls_bio_send(void *ctx, const unsigned char *dataptr, size_t size)
|
||||||
while (size_left) {
|
while (size_left) {
|
||||||
u16_t write_len = (u16_t)LWIP_MIN(size_left, 0xFFFF);
|
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);
|
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) {
|
if (err == ERR_OK) {
|
||||||
written += write_len;
|
written += write_len;
|
||||||
size_left -= 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",
|
LWIP_ASSERT("don't call tcp_output for listen-pcbs",
|
||||||
pcb->state != LISTEN);
|
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);
|
wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
|
||||||
|
|
||||||
seg = pcb->unsent;
|
seg = pcb->unsent;
|
||||||
|
|
|
@ -92,7 +92,7 @@ struct altcp_tls_config *altcp_tls_create_config_server_privkey_cert(const u8_t
|
||||||
/** @ingroup altcp_tls
|
/** @ingroup altcp_tls
|
||||||
* Create an ALTCP_TLS client configuration handle
|
* 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
|
/** @ingroup altcp_tls
|
||||||
* Create an ALTCP_TLS client configuration handle with two-way server/client authentication
|
* Create an ALTCP_TLS client configuration handle with two-way server/client authentication
|
||||||
|
|
|
@ -154,4 +154,10 @@
|
||||||
#define MEMP_MEM_INIT 1
|
#define MEMP_MEM_INIT 1
|
||||||
#define MEM_LIBC_MALLOC 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 */
|
#endif /* LWIP_UBOOT_LWIPOPTS_H */
|
||||||
|
|
|
@ -430,4 +430,16 @@ endif # SPL
|
||||||
|
|
||||||
endif # MBEDTLS_LIB_X509
|
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
|
endif # MBEDTLS_LIB
|
||||||
|
|
|
@ -26,6 +26,7 @@ mbedtls_lib_crypto-y := \
|
||||||
$(MBEDTLS_LIB_DIR)/platform_util.o \
|
$(MBEDTLS_LIB_DIR)/platform_util.o \
|
||||||
$(MBEDTLS_LIB_DIR)/constant_time.o \
|
$(MBEDTLS_LIB_DIR)/constant_time.o \
|
||||||
$(MBEDTLS_LIB_DIR)/md.o
|
$(MBEDTLS_LIB_DIR)/md.o
|
||||||
|
|
||||||
mbedtls_lib_crypto-$(CONFIG_$(SPL_)MD5_MBEDTLS) += $(MBEDTLS_LIB_DIR)/md5.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_)SHA1_MBEDTLS) += $(MBEDTLS_LIB_DIR)/sha1.o
|
||||||
mbedtls_lib_crypto-$(CONFIG_$(SPL_)SHA256_MBEDTLS) += \
|
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_DIR)/x509_crt.o
|
||||||
mbedtls_lib_x509-$(CONFIG_$(SPL_)PKCS7_MESSAGE_PARSER_MBEDTLS) += \
|
mbedtls_lib_x509-$(CONFIG_$(SPL_)PKCS7_MESSAGE_PARSER_MBEDTLS) += \
|
||||||
$(MBEDTLS_LIB_DIR)/pkcs7.o
|
$(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 */
|
#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 */
|
#endif /* #if defined CONFIG_MBEDTLS_LIB */
|
||||||
|
|
|
@ -37,7 +37,7 @@ config PROT_UDP_LWIP
|
||||||
|
|
||||||
config LWIP_TCP_WND
|
config LWIP_TCP_WND
|
||||||
int "Value of TCP_WND"
|
int "Value of TCP_WND"
|
||||||
default 8000 if ARCH_QEMU
|
default 32768 if ARCH_QEMU
|
||||||
default 3000000
|
default 3000000
|
||||||
help
|
help
|
||||||
Default value for TCP_WND in the lwIP configuration
|
Default value for TCP_WND in the lwIP configuration
|
||||||
|
|
|
@ -7,13 +7,17 @@
|
||||||
#include <efi_loader.h>
|
#include <efi_loader.h>
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
#include <lwip/apps/http_client.h>
|
#include <lwip/apps/http_client.h>
|
||||||
|
#include "lwip/altcp_tls.h"
|
||||||
#include <lwip/timeouts.h>
|
#include <lwip/timeouts.h>
|
||||||
|
#include <rng.h>
|
||||||
#include <mapmem.h>
|
#include <mapmem.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <dm/uclass.h>
|
||||||
|
|
||||||
#define SERVER_NAME_SIZE 200
|
#define SERVER_NAME_SIZE 200
|
||||||
#define HTTP_PORT_DEFAULT 80
|
#define HTTP_PORT_DEFAULT 80
|
||||||
|
#define HTTPS_PORT_DEFAULT 443
|
||||||
#define PROGRESS_PRINT_STEP_BYTES (100 * 1024)
|
#define PROGRESS_PRINT_STEP_BYTES (100 * 1024)
|
||||||
|
|
||||||
enum done_state {
|
enum done_state {
|
||||||
|
@ -32,18 +36,56 @@ struct wget_ctx {
|
||||||
enum done_state done;
|
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;
|
char *p, *pp;
|
||||||
long lport;
|
long lport;
|
||||||
|
size_t prefix_len = 0;
|
||||||
|
|
||||||
p = strstr(url, "http://");
|
if (!wget_validate_uri(url)) {
|
||||||
if (!p) {
|
log_err("Invalid URL. Use http(s)://\n");
|
||||||
log_err("only http:// is supported\n");
|
|
||||||
return -EINVAL;
|
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 */
|
/* Parse hostname */
|
||||||
pp = strchr(p, ':');
|
pp = strchr(p, ':');
|
||||||
|
@ -67,9 +109,8 @@ static int parse_url(char *url, char *host, u16 *port, char **path)
|
||||||
if (lport > 65535)
|
if (lport > 65535)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
*port = (u16)lport;
|
*port = (u16)lport;
|
||||||
} else {
|
|
||||||
*port = HTTP_PORT_DEFAULT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*pp != '/')
|
if (*pp != '/')
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
*path = pp;
|
*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)
|
static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri)
|
||||||
{
|
{
|
||||||
char server_name[SERVER_NAME_SIZE];
|
char server_name[SERVER_NAME_SIZE];
|
||||||
|
#if defined CONFIG_WGET_HTTPS
|
||||||
|
altcp_allocator_t tls_allocator;
|
||||||
|
#endif
|
||||||
httpc_connection_t conn;
|
httpc_connection_t conn;
|
||||||
httpc_state_t *state;
|
httpc_state_t *state;
|
||||||
struct netif *netif;
|
struct netif *netif;
|
||||||
struct wget_ctx ctx;
|
struct wget_ctx ctx;
|
||||||
char *path;
|
char *path;
|
||||||
u16 port;
|
u16 port;
|
||||||
|
bool is_https;
|
||||||
|
|
||||||
ctx.daddr = dst_addr;
|
ctx.daddr = dst_addr;
|
||||||
ctx.saved_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.prevsize = 0;
|
||||||
ctx.start_time = 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;
|
return CMD_RET_USAGE;
|
||||||
|
|
||||||
netif = net_lwip_new_netif(udev);
|
netif = net_lwip_new_netif(udev);
|
||||||
|
@ -232,6 +277,22 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
memset(&conn, 0, sizeof(conn));
|
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;
|
conn.result_fn = httpc_result_cb;
|
||||||
ctx.path = path;
|
ctx.path = path;
|
||||||
if (httpc_get_file_dns(server_name, port, path, &conn, httpc_recv_cb,
|
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;
|
char c;
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
char *str_copy, *s, *authority;
|
char *str_copy, *s, *authority;
|
||||||
|
size_t prefix_len = 0;
|
||||||
|
|
||||||
for (c = 0x1; c < 0x21; c++) {
|
for (c = 0x1; c < 0x21; c++) {
|
||||||
if (strchr(uri, c)) {
|
if (strchr(uri, c)) {
|
||||||
|
@ -323,15 +385,21 @@ bool wget_validate_uri(char *uri)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strchr(uri, 0x7f)) {
|
if (strchr(uri, 0x7f)) {
|
||||||
log_err("invalid character is used\n");
|
log_err("invalid character is used\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncmp(uri, "http://", 7)) {
|
if (!strncmp(uri, "http://", strlen("http://"))) {
|
||||||
log_err("only http:// is supported\n");
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
str_copy = strdup(uri);
|
str_copy = strdup(uri);
|
||||||
if (!str_copy)
|
if (!str_copy)
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Add table
Reference in a new issue