diff --git a/examples/dtls-wolfssl/Makefile b/examples/dtls-wolfssl/Makefile new file mode 100644 index 0000000000..a4a267bcdb --- /dev/null +++ b/examples/dtls-wolfssl/Makefile @@ -0,0 +1,63 @@ +# name of your application +APPLICATION = dtls_wolfssl + +# If no BOARD is found in the environment, use this default: +BOARD ?= native + +# This has to be the absolute path to the RIOT base directory: +RIOTBASE ?= $(CURDIR)/../.. + +# wolfSSL supports 32-bit architectures only +BOARD_BLACKLIST := arduino-duemilanove arduino-leonardo arduino-mega2560 arduino-nano arduino-uno \ + chronos jiminy-mega256rfr2 mega-xplained msb-430 msb-430h telosb \ + waspmote-pro wsn430-v1_3b wsn430-v1_4 z1 + +BOARD_INSUFFICIENT_MEMORY := airfy-beacon b-l072z-lrwan1 bluepill \ + calliope-mini cc2650-launchpad cc2650stk hifive1 i-nucleo-lrwan1 \ + maple-mini microbit nrf51dongle nrf6310 nucleo-f031k6 \ + nucleo-f042k6 nucleo-f303k8 nucleo-f303k8 nucleo-l031k6 nucleo-f030r8 \ + nucleo-f070rb nucleo-f072rb nucleo-f103rb nucleo-f302r8 nucleo-f334r8 \ + nucleo-l031k6 nucleo-l053r8 nucleo-l073rz opencm904 \ + saml11-xpro bluepill blackpill saml10-xpro \ + stm32l0538-disco \ + spark-core stm32f0discovery stm32mindev yunjia-nrf51822 + +# Include packages that pull up and auto-init the link layer. +# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present +USEMODULE += gnrc_netdev_default +USEMODULE += auto_init_gnrc_netif +# Specify the mandatory networking modules for IPv6 and UDP +USEMODULE += gnrc_ipv6_default +USEMODULE += gnrc_sock_udp + +# Add also the shell, some shell commands +USEMODULE += shell +USEMODULE += shell_commands + +USEPKG += wolfssl +USEMODULE += wolfcrypt +USEMODULE += wolfssl +USEMODULE += wolfssl_dtls + +# Select public key algorithm (or PSK) support fot ciphersuite(s): +#USEMODULE += wolfcrypt_ecc +#USEMODULE += wolfcrypt_rsa wolfcrypt_dh +USEMODULE += wolfssl_psk + +# Uncomment the following line to add debug symbols +#CFLAGS+=-g -ggdb3 + +CFLAGS += -DDTLS_DEFAULT_PORT=$(DTLS_PORT) -DDTLS_WOLFSSL -Wno-unused-parameter -Wno-unused-variable + +# A larger stack size is required if using ECC or RSA +CFLAGS += -DTHREAD_STACKSIZE_MAIN=\(3*THREAD_STACKSIZE_DEFAULT\) + +# Comment this out to disable code in RIOT that does safety checking +# which is not needed in a production environment but helps in the +# development process: +CFLAGS += -DDEVELHELP + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + +include $(RIOTBASE)/Makefile.include diff --git a/examples/dtls-wolfssl/README.md b/examples/dtls-wolfssl/README.md new file mode 100644 index 0000000000..d34a457e4b --- /dev/null +++ b/examples/dtls-wolfssl/README.md @@ -0,0 +1,49 @@ +# dtls_wolfssl example + +This example shows how to use DTLS with wolfSSL + +## SOCK vs. Socket + +This example is configured to use socks instead of sockets (over GNRC). +It's possible to use POSIX sockets, which give a more similar approach to the +UNIX version of wolfSSL. POSIX sockets are supported by RIOT-OS via lwIP, but +no example is available at this time. + +## Fast configuration (Between RIOT instances) + +### Prepare the bridge interface linking two tuntap + +```bash + ./../../dist/tools/tapsetup/tapsetup --create 2 +``` + +## Testing + +### Run the server +```bash +$ make all; PORT=tap1 make term +> ifconfig +``` +*copy the server address* + +```bash +> dtlss +``` +### Run the client +```bash +$ PORT=tap0 make term +> dtlsc +``` + +### Certificate/key + +Test certificate and key arrays are provided in `cert.c`. You can generate your own arrays starting from existing certificate and key in .der format using `xxd -i`. + +### Testing against host endpoints + +Riot-to-host can be tested against the DTLS examples provided in the [wolfSSL-examples](https://github.com/wolfSSL/wolfssl-examples/tree/master/dtls) repository. + +## Boards + +Boards that due to insufficient memory are not able to support GNRC are included +in the `BOARD_INSUFFICIENT_MEMORY`. diff --git a/examples/dtls-wolfssl/cert.c b/examples/dtls-wolfssl/cert.c new file mode 100644 index 0000000000..95a4cea3a8 --- /dev/null +++ b/examples/dtls-wolfssl/cert.c @@ -0,0 +1,307 @@ +/* Created from wolfssl-examples test certificate+keys, ECC/RSA. 28/08/2019 */ + +#ifdef MODULE_WOLFCRYPT_ECC +const unsigned char server_cert[] = { + 0x30, 0x82, 0x03, 0x50, 0x30, 0x82, 0x02, 0xf5, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x02, 0x10, 0x00, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x81, 0x97, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, + 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, + 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x77, + 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, + 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, + 0x6d, 0x65, 0x6e, 0x74, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0c, 0x0f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, + 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, + 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, + 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x31, 0x30, 0x32, + 0x30, 0x31, 0x38, 0x31, 0x39, 0x30, 0x36, 0x5a, 0x17, 0x0d, 0x32, 0x37, + 0x31, 0x30, 0x31, 0x38, 0x31, 0x38, 0x31, 0x39, 0x30, 0x36, 0x5a, 0x30, + 0x81, 0x8f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, + 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, + 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x45, 0x6c, 0x69, 0x70, 0x74, 0x69, 0x63, + 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x03, 0x45, + 0x43, 0x43, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x0f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, + 0x2e, 0x63, 0x6f, 0x6d, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, + 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, + 0x6d, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, + 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, + 0x03, 0x42, 0x00, 0x04, 0xbb, 0x33, 0xac, 0x4c, 0x27, 0x50, 0x4a, 0xc6, + 0x4a, 0xa5, 0x04, 0xc3, 0x3c, 0xde, 0x9f, 0x36, 0xdb, 0x72, 0x2d, 0xce, + 0x94, 0xea, 0x2b, 0xfa, 0xcb, 0x20, 0x09, 0x39, 0x2c, 0x16, 0xe8, 0x61, + 0x02, 0xe9, 0xaf, 0x4d, 0xd3, 0x02, 0x93, 0x9a, 0x31, 0x5b, 0x97, 0x92, + 0x21, 0x7f, 0xf0, 0xcf, 0x18, 0xda, 0x91, 0x11, 0x02, 0x34, 0x86, 0xe8, + 0x20, 0x58, 0x33, 0x0b, 0x80, 0x34, 0x89, 0xd8, 0xa3, 0x82, 0x01, 0x35, + 0x30, 0x82, 0x01, 0x31, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, + 0x02, 0x30, 0x00, 0x30, 0x11, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, + 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x06, 0x40, 0x30, 0x1d, + 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x5d, 0x5d, 0x26, + 0xef, 0xac, 0x7e, 0x36, 0xf9, 0x9b, 0x76, 0x15, 0x2b, 0x4a, 0x25, 0x02, + 0x23, 0xef, 0xb2, 0x89, 0x30, 0x30, 0x81, 0xcc, 0x06, 0x03, 0x55, 0x1d, + 0x23, 0x04, 0x81, 0xc4, 0x30, 0x81, 0xc1, 0x80, 0x14, 0x56, 0x8e, 0x9a, + 0xc3, 0xf0, 0x42, 0xde, 0x18, 0xb9, 0x45, 0x55, 0x6e, 0xf9, 0x93, 0xcf, + 0xea, 0xc3, 0xf3, 0xa5, 0x21, 0xa1, 0x81, 0x9d, 0xa4, 0x81, 0x9a, 0x30, + 0x81, 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, + 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, + 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, + 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x44, + 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x31, 0x18, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x77, 0x77, + 0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, + 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, + 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x09, 0x00, + 0x97, 0xb4, 0xbd, 0x16, 0x78, 0xf8, 0x47, 0xf2, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x03, 0xa8, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, + 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x0a, 0x06, + 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x49, 0x00, + 0x30, 0x46, 0x02, 0x21, 0x00, 0xbe, 0xb8, 0x58, 0xf0, 0xe4, 0x15, 0x01, + 0x1f, 0xdf, 0x70, 0x54, 0x73, 0x4a, 0x6c, 0x40, 0x1f, 0x77, 0xa8, 0xb4, + 0xeb, 0x52, 0x1e, 0xbf, 0xf5, 0x0d, 0xb1, 0x33, 0xca, 0x6a, 0xc4, 0x76, + 0xb9, 0x02, 0x21, 0x00, 0x97, 0x08, 0xde, 0x2c, 0x28, 0xc1, 0x45, 0x71, + 0xb6, 0x2c, 0x54, 0x87, 0x98, 0x63, 0x76, 0xa8, 0x21, 0x34, 0x90, 0xa8, + 0xf7, 0x9e, 0x3f, 0xfc, 0x02, 0xb0, 0xe7, 0xd3, 0x09, 0x31, 0x27, 0xe4 +}; +unsigned int server_cert_len = 852; +const unsigned char server_key[] = { + 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x45, 0xb6, 0x69, 0x02, 0x73, + 0x9c, 0x6c, 0x85, 0xa1, 0x38, 0x5b, 0x72, 0xe8, 0xe8, 0xc7, 0xac, 0xc4, + 0x03, 0x8d, 0x53, 0x35, 0x04, 0xfa, 0x6c, 0x28, 0xdc, 0x34, 0x8d, 0xe1, + 0xa8, 0x09, 0x8c, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, + 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0xbb, 0x33, 0xac, + 0x4c, 0x27, 0x50, 0x4a, 0xc6, 0x4a, 0xa5, 0x04, 0xc3, 0x3c, 0xde, 0x9f, + 0x36, 0xdb, 0x72, 0x2d, 0xce, 0x94, 0xea, 0x2b, 0xfa, 0xcb, 0x20, 0x09, + 0x39, 0x2c, 0x16, 0xe8, 0x61, 0x02, 0xe9, 0xaf, 0x4d, 0xd3, 0x02, 0x93, + 0x9a, 0x31, 0x5b, 0x97, 0x92, 0x21, 0x7f, 0xf0, 0xcf, 0x18, 0xda, 0x91, + 0x11, 0x02, 0x34, 0x86, 0xe8, 0x20, 0x58, 0x33, 0x0b, 0x80, 0x34, 0x89, + 0xd8 +}; +unsigned int server_key_len = 121; + +#endif + +#ifdef MODULE_WOLFCRYPT_RSA +const unsigned char server_cert[] = { + 0x30, 0x82, 0x04, 0x9e, 0x30, 0x82, 0x03, 0x86, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x94, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x07, 0x4d, 0x6f, + 0x6e, 0x74, 0x61, 0x6e, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x0c, 0x07, 0x42, 0x6f, 0x7a, 0x65, 0x6d, 0x61, 0x6e, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x53, 0x61, + 0x77, 0x74, 0x6f, 0x6f, 0x74, 0x68, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, + 0x55, 0x04, 0x0b, 0x0c, 0x0a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, + 0x69, 0x6e, 0x67, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0c, 0x0f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, + 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, + 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, + 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x34, 0x31, 0x33, + 0x31, 0x35, 0x32, 0x33, 0x31, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x30, + 0x31, 0x30, 0x37, 0x31, 0x35, 0x32, 0x33, 0x31, 0x30, 0x5a, 0x30, 0x81, + 0x90, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, + 0x07, 0x4d, 0x6f, 0x6e, 0x74, 0x61, 0x6e, 0x61, 0x31, 0x10, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x42, 0x6f, 0x7a, 0x65, 0x6d, + 0x61, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, + 0x07, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x31, 0x10, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x07, 0x53, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x0f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, + 0x2e, 0x63, 0x6f, 0x6d, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, + 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, + 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, + 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc0, 0x95, + 0x08, 0xe1, 0x57, 0x41, 0xf2, 0x71, 0x6d, 0xb7, 0xd2, 0x45, 0x41, 0x27, + 0x01, 0x65, 0xc6, 0x45, 0xae, 0xf2, 0xbc, 0x24, 0x30, 0xb8, 0x95, 0xce, + 0x2f, 0x4e, 0xd6, 0xf6, 0x1c, 0x88, 0xbc, 0x7c, 0x9f, 0xfb, 0xa8, 0x67, + 0x7f, 0xfe, 0x5c, 0x9c, 0x51, 0x75, 0xf7, 0x8a, 0xca, 0x07, 0xe7, 0x35, + 0x2f, 0x8f, 0xe1, 0xbd, 0x7b, 0xc0, 0x2f, 0x7c, 0xab, 0x64, 0xa8, 0x17, + 0xfc, 0xca, 0x5d, 0x7b, 0xba, 0xe0, 0x21, 0xe5, 0x72, 0x2e, 0x6f, 0x2e, + 0x86, 0xd8, 0x95, 0x73, 0xda, 0xac, 0x1b, 0x53, 0xb9, 0x5f, 0x3f, 0xd7, + 0x19, 0x0d, 0x25, 0x4f, 0xe1, 0x63, 0x63, 0x51, 0x8b, 0x0b, 0x64, 0x3f, + 0xad, 0x43, 0xb8, 0xa5, 0x1c, 0x5c, 0x34, 0xb3, 0xae, 0x00, 0xa0, 0x63, + 0xc5, 0xf6, 0x7f, 0x0b, 0x59, 0x68, 0x78, 0x73, 0xa6, 0x8c, 0x18, 0xa9, + 0x02, 0x6d, 0xaf, 0xc3, 0x19, 0x01, 0x2e, 0xb8, 0x10, 0xe3, 0xc6, 0xcc, + 0x40, 0xb4, 0x69, 0xa3, 0x46, 0x33, 0x69, 0x87, 0x6e, 0xc4, 0xbb, 0x17, + 0xa6, 0xf3, 0xe8, 0xdd, 0xad, 0x73, 0xbc, 0x7b, 0x2f, 0x21, 0xb5, 0xfd, + 0x66, 0x51, 0x0c, 0xbd, 0x54, 0xb3, 0xe1, 0x6d, 0x5f, 0x1c, 0xbc, 0x23, + 0x73, 0xd1, 0x09, 0x03, 0x89, 0x14, 0xd2, 0x10, 0xb9, 0x64, 0xc3, 0x2a, + 0xd0, 0xa1, 0x96, 0x4a, 0xbc, 0xe1, 0xd4, 0x1a, 0x5b, 0xc7, 0xa0, 0xc0, + 0xc1, 0x63, 0x78, 0x0f, 0x44, 0x37, 0x30, 0x32, 0x96, 0x80, 0x32, 0x23, + 0x95, 0xa1, 0x77, 0xba, 0x13, 0xd2, 0x97, 0x73, 0xe2, 0x5d, 0x25, 0xc9, + 0x6a, 0x0d, 0xc3, 0x39, 0x60, 0xa4, 0xb4, 0xb0, 0x69, 0x42, 0x42, 0x09, + 0xe9, 0xd8, 0x08, 0xbc, 0x33, 0x20, 0xb3, 0x58, 0x22, 0xa7, 0xaa, 0xeb, + 0xc4, 0xe1, 0xe6, 0x61, 0x83, 0xc5, 0xd2, 0x96, 0xdf, 0xd9, 0xd0, 0x4f, + 0xad, 0xd7, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xfc, 0x30, 0x81, + 0xf9, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0xb3, 0x11, 0x32, 0xc9, 0x92, 0x98, 0x84, 0xe2, 0xc9, 0xf8, 0xd0, 0x3b, + 0x6e, 0x03, 0x42, 0xca, 0x1f, 0x0e, 0x8e, 0x3c, 0x30, 0x81, 0xc9, 0x06, + 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xc1, 0x30, 0x81, 0xbe, 0x80, 0x14, + 0x27, 0x8e, 0x67, 0x11, 0x74, 0xc3, 0x26, 0x1d, 0x3f, 0xed, 0x33, 0x63, + 0xb3, 0xa4, 0xd8, 0x1d, 0x30, 0xe5, 0xe8, 0xd5, 0xa1, 0x81, 0x9a, 0xa4, + 0x81, 0x97, 0x30, 0x81, 0x94, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x07, 0x4d, 0x6f, 0x6e, 0x74, 0x61, 0x6e, 0x61, + 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x42, + 0x6f, 0x7a, 0x65, 0x6d, 0x61, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x53, 0x61, 0x77, 0x74, 0x6f, 0x6f, 0x74, + 0x68, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0a, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x31, 0x18, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x77, 0x77, + 0x2e, 0x77, 0x6f, 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, + 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, + 0x6c, 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x09, 0x00, + 0x86, 0xff, 0xf5, 0x8e, 0x10, 0xde, 0xb8, 0xfb, 0x30, 0x0c, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xb4, 0x54, 0x60, 0xad, 0xa0, 0x03, + 0x32, 0xde, 0x02, 0x7f, 0x21, 0x4a, 0x81, 0xc6, 0xed, 0xcd, 0xcd, 0xd8, + 0x12, 0x8a, 0xc0, 0xba, 0x82, 0x5b, 0x75, 0xad, 0x54, 0xe3, 0x7c, 0x80, + 0x6a, 0xac, 0x2e, 0x6c, 0x20, 0x4e, 0xbe, 0x4d, 0x82, 0xa7, 0x47, 0x13, + 0x5c, 0xf4, 0xc6, 0x6a, 0x2b, 0x10, 0x99, 0x58, 0xde, 0xab, 0x6b, 0x7c, + 0x22, 0x05, 0xc1, 0x83, 0x9d, 0xcb, 0xff, 0x3c, 0xe4, 0x2d, 0x57, 0x6a, + 0xa6, 0x96, 0xdf, 0xd3, 0xc1, 0x68, 0xe3, 0xd2, 0xc6, 0x83, 0x4b, 0x97, + 0xe2, 0xc6, 0x32, 0x0e, 0xbe, 0xc4, 0x03, 0xb9, 0x07, 0x8a, 0x5b, 0xb8, + 0x84, 0xba, 0xc5, 0x39, 0x3f, 0x1c, 0x58, 0xa7, 0x55, 0xd7, 0xf0, 0x9b, + 0xe8, 0xd2, 0x45, 0xb9, 0xe3, 0x83, 0x2e, 0xee, 0xb6, 0x71, 0x56, 0xb9, + 0x3a, 0xee, 0x3f, 0x27, 0xd8, 0x77, 0xe8, 0xfb, 0x44, 0x48, 0x65, 0x27, + 0x47, 0x4c, 0xfb, 0xfe, 0x72, 0xc3, 0xac, 0x05, 0x7b, 0x1d, 0xcb, 0xeb, + 0x5e, 0x65, 0x9a, 0xab, 0x02, 0xe4, 0x88, 0x5b, 0x3b, 0x8b, 0x0b, 0xc7, + 0xcc, 0xa9, 0xa6, 0x8b, 0xe1, 0x87, 0xb0, 0x19, 0x1a, 0x0c, 0x28, 0x58, + 0x6f, 0x99, 0x52, 0x7e, 0xed, 0xb0, 0x3a, 0x68, 0x3b, 0x8c, 0x0a, 0x08, + 0x74, 0x72, 0xab, 0xb9, 0x09, 0xc5, 0xed, 0x04, 0x7e, 0x6f, 0x0b, 0x1c, + 0x09, 0x21, 0xd0, 0xcd, 0x7f, 0xf9, 0xc4, 0x5e, 0x27, 0x20, 0xe4, 0x85, + 0x73, 0x52, 0x05, 0xd2, 0xba, 0xf8, 0xd5, 0x8f, 0x41, 0xcc, 0x23, 0x2e, + 0x12, 0x6d, 0xbc, 0x31, 0x98, 0xe7, 0x63, 0xa3, 0x8e, 0x26, 0xcd, 0xe8, + 0x2b, 0x88, 0xee, 0xe2, 0xfe, 0x3a, 0x74, 0x52, 0x34, 0x0e, 0xfd, 0x12, + 0xe5, 0x5e, 0x69, 0x50, 0x20, 0x31, 0x34, 0xe4, 0x31, 0xf1, 0xe7, 0xe4, + 0x5b, 0x03, 0x13, 0xda, 0xac, 0x41, 0x6c, 0xe7, 0xcf, 0x2b +}; +const unsigned int server_cert_len = 1186; + +const unsigned char server_key[] = { + 0x30, 0x82, 0x04, 0xa5, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, + 0xc0, 0x95, 0x08, 0xe1, 0x57, 0x41, 0xf2, 0x71, 0x6d, 0xb7, 0xd2, 0x45, + 0x41, 0x27, 0x01, 0x65, 0xc6, 0x45, 0xae, 0xf2, 0xbc, 0x24, 0x30, 0xb8, + 0x95, 0xce, 0x2f, 0x4e, 0xd6, 0xf6, 0x1c, 0x88, 0xbc, 0x7c, 0x9f, 0xfb, + 0xa8, 0x67, 0x7f, 0xfe, 0x5c, 0x9c, 0x51, 0x75, 0xf7, 0x8a, 0xca, 0x07, + 0xe7, 0x35, 0x2f, 0x8f, 0xe1, 0xbd, 0x7b, 0xc0, 0x2f, 0x7c, 0xab, 0x64, + 0xa8, 0x17, 0xfc, 0xca, 0x5d, 0x7b, 0xba, 0xe0, 0x21, 0xe5, 0x72, 0x2e, + 0x6f, 0x2e, 0x86, 0xd8, 0x95, 0x73, 0xda, 0xac, 0x1b, 0x53, 0xb9, 0x5f, + 0x3f, 0xd7, 0x19, 0x0d, 0x25, 0x4f, 0xe1, 0x63, 0x63, 0x51, 0x8b, 0x0b, + 0x64, 0x3f, 0xad, 0x43, 0xb8, 0xa5, 0x1c, 0x5c, 0x34, 0xb3, 0xae, 0x00, + 0xa0, 0x63, 0xc5, 0xf6, 0x7f, 0x0b, 0x59, 0x68, 0x78, 0x73, 0xa6, 0x8c, + 0x18, 0xa9, 0x02, 0x6d, 0xaf, 0xc3, 0x19, 0x01, 0x2e, 0xb8, 0x10, 0xe3, + 0xc6, 0xcc, 0x40, 0xb4, 0x69, 0xa3, 0x46, 0x33, 0x69, 0x87, 0x6e, 0xc4, + 0xbb, 0x17, 0xa6, 0xf3, 0xe8, 0xdd, 0xad, 0x73, 0xbc, 0x7b, 0x2f, 0x21, + 0xb5, 0xfd, 0x66, 0x51, 0x0c, 0xbd, 0x54, 0xb3, 0xe1, 0x6d, 0x5f, 0x1c, + 0xbc, 0x23, 0x73, 0xd1, 0x09, 0x03, 0x89, 0x14, 0xd2, 0x10, 0xb9, 0x64, + 0xc3, 0x2a, 0xd0, 0xa1, 0x96, 0x4a, 0xbc, 0xe1, 0xd4, 0x1a, 0x5b, 0xc7, + 0xa0, 0xc0, 0xc1, 0x63, 0x78, 0x0f, 0x44, 0x37, 0x30, 0x32, 0x96, 0x80, + 0x32, 0x23, 0x95, 0xa1, 0x77, 0xba, 0x13, 0xd2, 0x97, 0x73, 0xe2, 0x5d, + 0x25, 0xc9, 0x6a, 0x0d, 0xc3, 0x39, 0x60, 0xa4, 0xb4, 0xb0, 0x69, 0x42, + 0x42, 0x09, 0xe9, 0xd8, 0x08, 0xbc, 0x33, 0x20, 0xb3, 0x58, 0x22, 0xa7, + 0xaa, 0xeb, 0xc4, 0xe1, 0xe6, 0x61, 0x83, 0xc5, 0xd2, 0x96, 0xdf, 0xd9, + 0xd0, 0x4f, 0xad, 0xd7, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, + 0x01, 0x00, 0x9a, 0xd0, 0x34, 0x0f, 0x52, 0x62, 0x05, 0x50, 0x01, 0xef, + 0x9f, 0xed, 0x64, 0x6e, 0xc2, 0xc4, 0xda, 0x1a, 0xf2, 0x84, 0xd7, 0x92, + 0x10, 0x48, 0x92, 0xc4, 0xe9, 0x6a, 0xeb, 0x8b, 0x75, 0x6c, 0xc6, 0x79, + 0x38, 0xf2, 0xc9, 0x72, 0x4a, 0x86, 0x64, 0x54, 0x95, 0x77, 0xcb, 0xc3, + 0x9a, 0x9d, 0xb7, 0xd4, 0x1d, 0xa4, 0x00, 0xc8, 0x9e, 0x4e, 0xe4, 0xdd, + 0xc7, 0xba, 0x67, 0x16, 0xc1, 0x74, 0xbc, 0xa9, 0xd6, 0x94, 0x8f, 0x2b, + 0x30, 0x1a, 0xfb, 0xed, 0xdf, 0x21, 0x05, 0x23, 0xd9, 0x4a, 0x39, 0xbd, + 0x98, 0x6b, 0x65, 0x9a, 0xb8, 0xdc, 0xc4, 0x7d, 0xee, 0xa6, 0x43, 0x15, + 0x2e, 0x3d, 0xbe, 0x1d, 0x22, 0x60, 0x2a, 0x73, 0x30, 0xd5, 0x3e, 0xd8, + 0xa2, 0xac, 0x86, 0x43, 0x2e, 0xc4, 0xf5, 0x64, 0x5e, 0x3f, 0x89, 0x75, + 0x0f, 0x11, 0xd8, 0x51, 0x25, 0x4e, 0x9f, 0xd8, 0xaa, 0xa3, 0xce, 0x60, + 0xb3, 0xe2, 0x8a, 0xd9, 0x7e, 0x1b, 0xf0, 0x64, 0xca, 0x9a, 0x5b, 0x05, + 0x0b, 0x5b, 0xaa, 0xcb, 0xe5, 0xe3, 0x3f, 0x6e, 0x32, 0x22, 0x05, 0xf3, + 0xd0, 0xfa, 0xef, 0x74, 0x52, 0x81, 0xe2, 0x5f, 0x74, 0xd3, 0xbd, 0xff, + 0x31, 0x83, 0x45, 0x75, 0xfa, 0x63, 0x7a, 0x97, 0x2e, 0xd6, 0xb6, 0x19, + 0xc6, 0x92, 0x26, 0xe4, 0x28, 0x06, 0x50, 0x50, 0x0e, 0x78, 0x2e, 0xa9, + 0x78, 0x0d, 0x14, 0x97, 0xb4, 0x12, 0xd8, 0x31, 0x40, 0xab, 0xa1, 0x01, + 0x41, 0xc2, 0x30, 0xf8, 0x07, 0x5f, 0x16, 0xe4, 0x61, 0x77, 0xd2, 0x60, + 0xf2, 0x9f, 0x8d, 0xe8, 0xf4, 0xba, 0xeb, 0x63, 0xde, 0x2a, 0x97, 0x81, + 0xef, 0x4c, 0x6c, 0xe6, 0x55, 0x34, 0x51, 0x2b, 0x28, 0x34, 0xf4, 0x53, + 0x1c, 0xc4, 0x58, 0x0a, 0x3f, 0xbb, 0xaf, 0xb5, 0xf7, 0x4a, 0x85, 0x43, + 0x2d, 0x3c, 0xf1, 0x58, 0x58, 0x81, 0x02, 0x81, 0x81, 0x00, 0xf2, 0x2c, + 0x54, 0x76, 0x39, 0x23, 0x63, 0xc9, 0x10, 0x32, 0xb7, 0x93, 0xad, 0xaf, + 0xbe, 0x19, 0x75, 0x96, 0x81, 0x64, 0xe6, 0xb5, 0xb8, 0x89, 0x42, 0x41, + 0xd1, 0x6d, 0xd0, 0x1c, 0x1b, 0xf8, 0x1b, 0xac, 0x69, 0xcb, 0x36, 0x3c, + 0x64, 0x7d, 0xdc, 0xf4, 0x19, 0xb8, 0xc3, 0x60, 0xb1, 0x57, 0x48, 0x5f, + 0x52, 0x4f, 0x59, 0x3a, 0x55, 0x7f, 0x32, 0xc0, 0x19, 0x43, 0x50, 0x3f, + 0xae, 0xce, 0x6f, 0x17, 0xf3, 0x0e, 0x9f, 0x40, 0xca, 0x4e, 0xad, 0x15, + 0x3b, 0xc9, 0x79, 0xe9, 0xc0, 0x59, 0x38, 0x73, 0x70, 0x9c, 0x0a, 0x7c, + 0xc9, 0x3a, 0x48, 0x32, 0xa7, 0xd8, 0x49, 0x75, 0x0a, 0x85, 0xc2, 0xc2, + 0xfd, 0x15, 0x73, 0xda, 0x99, 0x09, 0x2a, 0x69, 0x9a, 0x9f, 0x0a, 0x71, + 0xbf, 0xb0, 0x04, 0xa6, 0x8c, 0x7a, 0x5a, 0x6f, 0x48, 0x5a, 0x54, 0x3b, + 0xc6, 0xb1, 0x53, 0x17, 0xdf, 0xe7, 0x02, 0x81, 0x81, 0x00, 0xcb, 0x93, + 0xde, 0x77, 0x15, 0x5d, 0xb7, 0x5c, 0x5c, 0x7c, 0xd8, 0x90, 0xa9, 0x98, + 0x2d, 0xd6, 0x69, 0x0e, 0x63, 0xb3, 0xa3, 0xdc, 0xa6, 0xcc, 0x8b, 0x6a, + 0xa4, 0xa2, 0x12, 0x8c, 0x8e, 0x7b, 0x48, 0x2c, 0xb2, 0x4b, 0x37, 0xdc, + 0x06, 0x18, 0x7d, 0xea, 0xfe, 0x76, 0xa1, 0xd4, 0xa1, 0xe9, 0x3f, 0x0d, + 0xcd, 0x1b, 0x5f, 0xaf, 0x5f, 0x9e, 0x96, 0x5b, 0x5b, 0x0f, 0xa1, 0x7c, + 0xaf, 0xb3, 0x9b, 0x90, 0xdb, 0x57, 0x73, 0x3a, 0xed, 0xb0, 0x23, 0x44, + 0xae, 0x41, 0x4f, 0x1f, 0x07, 0x42, 0x13, 0x23, 0x4c, 0xcb, 0xfa, 0xf4, + 0x14, 0xa4, 0xd5, 0xf7, 0x9e, 0x36, 0x7c, 0x5b, 0x9f, 0xa8, 0x3c, 0xc1, + 0x85, 0x5f, 0x74, 0xd2, 0x39, 0x2d, 0xff, 0xd0, 0x84, 0xdf, 0xfb, 0xb3, + 0x20, 0x7a, 0x2e, 0x9b, 0x17, 0xae, 0xe6, 0xba, 0x0b, 0xae, 0x5f, 0x53, + 0xa4, 0x52, 0xed, 0x1b, 0xc4, 0x91, 0x02, 0x81, 0x81, 0x00, 0xec, 0x98, + 0xda, 0xbb, 0xd5, 0xfe, 0xf9, 0x52, 0x4a, 0x7d, 0x02, 0x55, 0x49, 0x6f, + 0x55, 0x6e, 0x52, 0x2f, 0x84, 0xa3, 0x2b, 0xb3, 0x86, 0x62, 0xb3, 0x54, + 0xd2, 0x63, 0x52, 0xda, 0xe3, 0x88, 0x76, 0xa0, 0xef, 0x8b, 0x15, 0xa5, + 0xd3, 0x18, 0x14, 0x72, 0x77, 0x5e, 0xc7, 0xa3, 0x04, 0x1f, 0x9e, 0x19, + 0x62, 0xb5, 0x1b, 0x1b, 0x9e, 0xc3, 0xf2, 0xb5, 0x32, 0xf9, 0x4c, 0xc1, + 0xaa, 0xeb, 0x0c, 0x26, 0x7d, 0xd4, 0x5f, 0x4a, 0x51, 0x5c, 0xa4, 0x45, + 0x06, 0x70, 0x44, 0xa7, 0x56, 0xc0, 0xd4, 0x22, 0x14, 0x76, 0x9e, 0xd8, + 0x63, 0x50, 0x89, 0x90, 0xd3, 0xe2, 0xbf, 0x81, 0x95, 0x92, 0x31, 0x41, + 0x87, 0x39, 0x1a, 0x43, 0x0b, 0x18, 0xa5, 0x53, 0x1f, 0x39, 0x1a, 0x5f, + 0x1f, 0x43, 0xbc, 0x87, 0x6a, 0xdf, 0x6e, 0xd3, 0x22, 0x00, 0xfe, 0x22, + 0x98, 0x70, 0x4e, 0x1a, 0x19, 0x29, 0x02, 0x81, 0x81, 0x00, 0x8a, 0x41, + 0x56, 0x28, 0x51, 0x9e, 0x5f, 0xd4, 0x9e, 0x0b, 0x3b, 0x98, 0xa3, 0x54, + 0xf2, 0x6c, 0x56, 0xd4, 0xaa, 0xe9, 0x69, 0x33, 0x85, 0x24, 0x0c, 0xda, + 0xd4, 0x0c, 0x2d, 0xc4, 0xbf, 0x4f, 0x02, 0x69, 0x38, 0x7c, 0xd4, 0xe6, + 0xdc, 0x4c, 0xed, 0xd7, 0x16, 0x11, 0xc3, 0x3e, 0x00, 0xe7, 0xc3, 0x26, + 0xc0, 0x51, 0x02, 0xde, 0xbb, 0x75, 0x9c, 0x6f, 0x56, 0x9c, 0x7a, 0xf3, + 0x8e, 0xef, 0xcf, 0x8a, 0xc5, 0x2b, 0xd2, 0xda, 0x06, 0x6a, 0x44, 0xc9, + 0x73, 0xfe, 0x6e, 0x99, 0x87, 0xf8, 0x5b, 0xbe, 0xf1, 0x7c, 0xe6, 0x65, + 0xb5, 0x4f, 0x6c, 0xf0, 0xc9, 0xc5, 0xff, 0x16, 0xca, 0x8b, 0x1b, 0x17, + 0xe2, 0x58, 0x3d, 0xa2, 0x37, 0xab, 0x01, 0xbc, 0xbf, 0x40, 0xce, 0x53, + 0x8c, 0x8e, 0xed, 0xef, 0xee, 0x59, 0x9d, 0xe0, 0x63, 0xe6, 0x7c, 0x5e, + 0xf5, 0x8e, 0x4b, 0xf1, 0x3b, 0xc1, 0x02, 0x81, 0x80, 0x4d, 0x45, 0xf9, + 0x40, 0x8c, 0xc5, 0x5b, 0xf4, 0x2a, 0x1a, 0x8a, 0xb4, 0xf2, 0x1c, 0xac, + 0x6b, 0xe9, 0x0c, 0x56, 0x36, 0xb7, 0x4e, 0x72, 0x96, 0xd5, 0xe5, 0x8a, + 0xd2, 0xe2, 0xff, 0xf1, 0xf1, 0x18, 0x13, 0x3d, 0x86, 0x09, 0xb8, 0xd8, + 0x76, 0xa7, 0xc9, 0x1c, 0x71, 0x52, 0x94, 0x30, 0x43, 0xe0, 0xf1, 0x78, + 0x74, 0xfd, 0x61, 0x1b, 0x4c, 0x09, 0xcc, 0xe6, 0x68, 0x2a, 0x71, 0xad, + 0x1c, 0xdf, 0x43, 0xbc, 0x56, 0xdb, 0xa5, 0xa4, 0xbe, 0x35, 0x70, 0xa4, + 0x5e, 0xcf, 0x4f, 0xfc, 0x00, 0x55, 0x99, 0x3a, 0x3d, 0x23, 0xcf, 0x67, + 0x5a, 0xf5, 0x22, 0xf8, 0xb5, 0x29, 0xd0, 0x44, 0x11, 0xeb, 0x35, 0x2e, + 0x46, 0xbe, 0xfd, 0x8e, 0x18, 0xb2, 0x5f, 0xa8, 0xbf, 0x19, 0x32, 0xa1, + 0xf5, 0xdc, 0x03, 0xe6, 0x7c, 0x9a, 0x1f, 0x0c, 0x7c, 0xa9, 0xb0, 0x0e, + 0x21, 0x37, 0x3b, 0xf1, 0xb0 +}; +const unsigned int server_key_len = 1193; +#endif + +#ifdef MODULE_WOLFSSL_PSK +const unsigned char server_key[1] = { 0 }; +const unsigned int server_key_len = 0; +#endif diff --git a/examples/dtls-wolfssl/dtls-client.c b/examples/dtls-wolfssl/dtls-client.c new file mode 100644 index 0000000000..14b96e8cd4 --- /dev/null +++ b/examples/dtls-wolfssl/dtls-client.c @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2019 Daniele Lacamera + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @file + * @brief Demonstrating DTLS 1.2 client using wolfSSL + * + * @author Daniele Lacamera + * @} + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "log.h" + +#define SERVER_PORT 11111 +#define APP_DTLS_BUF_SIZE 64 + +extern const unsigned char server_cert[]; +extern const unsigned long server_cert_len; + +static sock_tls_t skv; +static sock_tls_t *sk = &skv; + +static void usage(const char *cmd_name) +{ + LOG(LOG_ERROR, "Usage: %s \n", cmd_name); +} + +#ifdef MODULE_WOLFSSL_PSK +/* identity is OpenSSL testing default for openssl s_client, keep same */ +static const char* kIdentityStr = "Client_identity"; + +static inline unsigned int my_psk_client_cb(WOLFSSL* ssl, const char* hint, + char* identity, unsigned int id_max_len, unsigned char* key, + unsigned int key_max_len) +{ + (void)ssl; + (void)hint; + (void)key_max_len; + + /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */ + strncpy(identity, kIdentityStr, id_max_len); + + if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) { + /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using + unsigned binary */ + key[0] = 0x1a; + key[1] = 0x2b; + key[2] = 0x3c; + key[3] = 0x4d; + + return 4; /* length of key in octets or 0 for error */ + } + else { + int i; + int b = 0x01; + + for (i = 0; i < 32; i++, b += 0x22) { + if (b >= 0x100) + b = 0x01; + key[i] = b; + } + + return 32; /* length of key in octets or 0 for error */ + } +} +#endif + +int dtls_client(int argc, char **argv) +{ + int ret = 0; + char buf[APP_DTLS_BUF_SIZE] = "Hello from DTLS client!"; + int iface; + char *addr_str; + int connect_timeout = 0; + const int max_connect_timeouts = 5; + + if (argc != 2) { + usage(argv[0]); + return -1; + } + + addr_str = argv[1]; + sock_udp_ep_t local = SOCK_IPV6_EP_ANY; + sock_udp_ep_t remote = SOCK_IPV6_EP_ANY; + + /* Parsing
*/ + iface = ipv6_addr_split_iface(addr_str); + if (iface == -1) { + if (gnrc_netif_numof() == 1) { + /* assign the single interface found in gnrc_netif_numof() */ + remote.netif = (uint16_t)gnrc_netif_iter(NULL)->pid; + } + } + else { + if (gnrc_netif_get_by_pid(iface) == NULL) { + LOG(LOG_ERROR, "ERROR: interface not valid"); + usage(argv[0]); + return -1; + } + remote.netif = (uint16_t)gnrc_netif_iter(NULL)->pid; + } + if (ipv6_addr_from_str((ipv6_addr_t *)remote.addr.ipv6, addr_str) == NULL) { + LOG(LOG_ERROR, "ERROR: unable to parse destination address"); + usage(argv[0]); + return -1; + } + remote.port = SERVER_PORT; + if (sock_dtls_create(sk, &local, &remote, 0, wolfDTLSv1_2_client_method()) != 0) { + LOG(LOG_ERROR, "ERROR: Unable to create DTLS sock"); + return -1; + } + +#ifndef MODULE_WOLFSSL_PSK + /* Disable certificate validation from the client side */ + wolfSSL_CTX_set_verify(sk->ctx, SSL_VERIFY_NONE, 0); + + /* Load certificate file for the DTLS client */ + if (wolfSSL_CTX_use_certificate_buffer(sk->ctx, server_cert, + server_cert_len, SSL_FILETYPE_ASN1 ) != SSL_SUCCESS) + { + LOG(LOG_ERROR, "Error loading cert buffer\n"); + return -1; + } + +#else /* !def MODULE_WOLFSSL_PSK */ + wolfSSL_CTX_set_psk_client_callback(sk->ctx, my_psk_client_cb); +#endif + + if (sock_dtls_session_create(sk) < 0) + return -1; + wolfSSL_dtls_set_timeout_init(sk->ssl, 5); + LOG(LOG_INFO, "connecting to server..."); + /* attempt to connect until the connection is successful */ + do { + ret = wolfSSL_connect(sk->ssl); + if ((ret != SSL_SUCCESS)) { + if(wolfSSL_get_error(sk->ssl, ret) == SOCKET_ERROR_E) { + LOG(LOG_WARNING, "Socket error: reconnecting...\n"); + sock_dtls_session_destroy(sk); + connect_timeout = 0; + if (sock_dtls_session_create(sk) < 0) + return -1; + } + if ((wolfSSL_get_error(sk->ssl, ret) == WOLFSSL_ERROR_WANT_READ) && + (connect_timeout++ >= max_connect_timeouts)) { + LOG(LOG_WARNING, "Server not responding: reconnecting...\n"); + sock_dtls_session_destroy(sk); + connect_timeout = 0; + if (sock_dtls_session_create(sk) < 0) + return -1; + } + } + } while(ret != SSL_SUCCESS); + + /* set remote endpoint */ + sock_dtls_set_endpoint(sk, &remote); + + /* send the hello message */ + wolfSSL_write(sk->ssl, buf, strlen(buf)); + + /* wait for a reply, indefinitely */ + do { + ret = wolfSSL_read(sk->ssl, buf, APP_DTLS_BUF_SIZE - 1); + LOG(LOG_INFO, "wolfSSL_read returned %d\r\n", ret); + } while (ret <= 0); + buf[ret] = (char)0; + LOG(LOG_INFO, "Received: '%s'\r\n", buf); + + /* Clean up and exit. */ + LOG(LOG_INFO, "Closing connection.\r\n"); + sock_dtls_session_destroy(sk); + sock_dtls_close(sk); + return 0; +} diff --git a/examples/dtls-wolfssl/dtls-server.c b/examples/dtls-wolfssl/dtls-server.c new file mode 100644 index 0000000000..81da6e4db6 --- /dev/null +++ b/examples/dtls-wolfssl/dtls-server.c @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2019 Daniele Lacamera + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @file + * @brief Demonstrating DTLS 1.2 server using wolfSSL + * + * @author Daniele Lacamera + * @} + */ + +#include +#include + +#include + +#include + +#include +#include +#include + +#include "log.h" + +#define SERVER_PORT 11111 +#define DEBUG 1 +extern const unsigned char server_cert[]; +extern const unsigned char server_key[]; +extern unsigned int server_cert_len; +extern unsigned int server_key_len; + +static sock_tls_t skv; +static sock_tls_t *sk = &skv; + +static const char Test_dtls_string[] = "DTLS OK!"; + +#ifdef MODULE_WOLFSSL_PSK +/* identity is OpenSSL testing default for openssl s_client, keep same */ +static const char* kIdentityStr = "Client_identity"; + +static inline unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity, + unsigned char* key, unsigned int key_max_len) +{ + (void)ssl; + (void)key_max_len; + + /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */ + if (strncmp(identity, kIdentityStr, strlen(kIdentityStr)) != 0) + return 0; + + if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) { + /* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using + unsigned binary */ + key[0] = 0x1a; + key[1] = 0x2b; + key[2] = 0x3c; + key[3] = 0x4d; + + return 4; /* length of key in octets or 0 for error */ + } + else { + int i; + int b = 0x01; + + for (i = 0; i < 32; i++, b += 0x22) { + if (b >= 0x100) + b = 0x01; + key[i] = b; + } + + return 32; /* length of key in octets or 0 for error */ + } +} +#endif /* MODULE_WOLFSSL_PSK */ + +#define APP_DTLS_BUF_SIZE 64 + +int dtls_server(int argc, char **argv) +{ + char buf[APP_DTLS_BUF_SIZE]; + int ret; + sock_udp_ep_t local = SOCK_IPV6_EP_ANY; + local.port = SERVER_PORT; + + (void)argc; + (void)argv; + + if (sock_dtls_create(sk, &local, NULL, 0, wolfDTLSv1_2_server_method()) != 0) { + LOG(LOG_ERROR, "ERROR: Unable to create DTLS sock\r\n"); + return -1; + } + +#ifndef MODULE_WOLFSSL_PSK + /* Load certificate file for the DTLS server */ + if (wolfSSL_CTX_use_certificate_buffer(sk->ctx, server_cert, + server_cert_len, SSL_FILETYPE_ASN1 ) != SSL_SUCCESS) + { + LOG(LOG_ERROR, "Failed to load certificate from memory.\r\n"); + return -1; + } + + /* Load the private key */ + if (wolfSSL_CTX_use_PrivateKey_buffer(sk->ctx, server_key, + server_key_len, SSL_FILETYPE_ASN1 ) != SSL_SUCCESS) + { + LOG(LOG_ERROR, "Failed to load private key from memory.\r\n"); + return -1; + } +#else + wolfSSL_CTX_set_psk_server_callback(sk->ctx, my_psk_server_cb); + wolfSSL_CTX_use_psk_identity_hint(sk->ctx, "hint"); +#endif /* MODULE_WOLFSSL_PSK */ + + /* Create the DTLS session */ + ret = sock_dtls_session_create(sk); + if (ret < 0) + { + LOG(LOG_ERROR, "Failed to create DTLS session (err: %s)\r\n", strerror(-ret)); + return -1; + } + + LOG(LOG_INFO, "Listening on %d\n", SERVER_PORT); + while(1) { + /* Wait until a new client connects */ + ret = wolfSSL_accept(sk->ssl); + if (ret != SSL_SUCCESS) { + if (wolfSSL_get_error(sk->ssl, ret) != WOLFSSL_ERROR_WANT_READ) { + sock_dtls_session_destroy(sk); + if (sock_dtls_session_create(sk) < 0) + return -1; + } + continue; + } + + /* Wait until data is received */ + LOG(LOG_INFO, "Connection accepted\r\n"); + ret = wolfSSL_read(sk->ssl, buf, APP_DTLS_BUF_SIZE); + if (ret > 0) { + buf[ret] = (char)0; + LOG(LOG_INFO, "Received '%s'\r\n", buf); + } + + /* Send reply */ + LOG(LOG_INFO, "Sending 'DTLS OK'...\r\n"); + wolfSSL_write(sk->ssl, Test_dtls_string, sizeof(Test_dtls_string)); + + /* Cleanup/shutdown */ + LOG(LOG_INFO, "Closing connection.\r\n"); + sock_dtls_session_destroy(sk); + sock_dtls_close(sk); + break; + } + return 0; +} diff --git a/examples/dtls-wolfssl/main.c b/examples/dtls-wolfssl/main.c new file mode 100644 index 0000000000..9d02945363 --- /dev/null +++ b/examples/dtls-wolfssl/main.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2019 Daniele Lacamera + * + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + + +/** + * @ingroup examples + * @{ + * + * @file + * @brief Example application for DTLS 1.2 using wolfSSL + * + * @author Daniele Lacamera + * + * @} + */ + +#include + +#include "shell.h" +#include "msg.h" +#include "log.h" + + +#ifdef WITH_RIOT_SOCKETS +#error RIOT-OS is set to use sockets but this DTLS app is configured for socks. +#endif + +#define MAIN_QUEUE_SIZE (8) +static msg_t _main_msg_queue[MAIN_QUEUE_SIZE]; + +extern int dtls_client(int argc, char **argv); +extern int dtls_server(int argc, char **argv); + +#ifdef MODULE_WOLFCRYPT_TEST +extern int wolfcrypt_test(void* args); +static int wolftest(int argc, char **argv) +{ + (void)argc; + (void)argv; + wolfcrypt_test(NULL); + return 0; +} +#endif + +static const shell_command_t shell_commands[] = { + { "dtlsc", "Start a DTLS client", dtls_client }, + { "dtlss", "Start and stop a DTLS server", dtls_server }, +#ifdef MODULE_WOLFCRYPT_TEST + { "wolftest", "Perform wolfcrypt porting test", wolftest }, +#endif + { NULL, NULL, NULL } +}; + +int main(void) +{ + /* we need a message queue for the thread running the shell in order to + * receive potentially fast incoming networking packets */ + msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE); + LOG(LOG_INFO, "RIOT wolfSSL DTLS testing implementation"); + wolfSSL_Init(); + wolfSSL_Debugging_ON(); + + /* start shell */ + LOG(LOG_INFO, "All up, running the shell now"); + char line_buf[SHELL_DEFAULT_BUFSIZE]; + shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); + + /* should be never reached */ + return 0; +} diff --git a/pkg/wolfssl/Makefile b/pkg/wolfssl/Makefile new file mode 100644 index 0000000000..e493ae89aa --- /dev/null +++ b/pkg/wolfssl/Makefile @@ -0,0 +1,18 @@ +PKG_NAME=wolfssl +PKG_URL=https://github.com/wolfssl/wolfssl.git + +# Current version: v4.1.0+ +PKG_VERSION=eaeaaf12c11dd52ab0cd6833252ed559656e9826 +PKG_LICENSE=GPLv2 + +.PHONY: all +all: # Nothing to do here when building + +prepare: + cp Makefile.wolfssl $(PKG_BUILDDIR)/src/Makefile + cp Makefile.wolfcrypt $(PKG_BUILDDIR)/wolfcrypt/src/Makefile + touch $(PKG_BUILDDIR)/wolfssl.a + cp Makefile.wolfcrypt-test $(PKG_BUILDDIR)/wolfcrypt/test/Makefile + cp Makefile.wolfcrypt-benchmark $(PKG_BUILDDIR)/wolfcrypt/benchmark/Makefile + +include $(RIOTBASE)/pkg/pkg.mk diff --git a/pkg/wolfssl/Makefile.dep b/pkg/wolfssl/Makefile.dep new file mode 100644 index 0000000000..9352cdb326 --- /dev/null +++ b/pkg/wolfssl/Makefile.dep @@ -0,0 +1,84 @@ + +ifneq (,$(filter wolfcrypt-test,$(USEMODULE))) + USEMODULE += wolfcrypt + USEMODULE += wolfcrypt_coding +endif + +ifneq (,$(filter wolfcrypt-benchmark,$(USEMODULE))) + USEMODULE += wolfcrypt + USEMODULE += wolfcrypt_coding + USEMODULE += printf_float + USEMODULE += xtimer +endif + +ifneq (,$(filter wolfcrypt_poly1305,$(USEMODULE))) + ifneq (,$(filter wolfcrypt_chacha,$(USEMODULE))) + USEMODULE += wolfcrypt_chacha20_poly1305 + endif +endif + +ifneq (,$(filter wolfcrypt_ed25519,$(USEMODULE))) + USEMODULE += wolfcrypt_sha512 +endif + +ifneq (,$(filter wolfcrypt_aes,$(USEMODULE))) + USEMODULE += wolfcrypt_cmac + USEMODULE += wolfcrypt_coding +endif + +ifneq (,$(filter wolfcrypt_pwdbased,$(USEMODULE))) + USEMODULE += wolfcrypt_pkcs12 +endif + +ifneq (,$(filter wolfcrypt_asn,$(USEMODULE))) + USEMODULE += wolfcrypt_pkcs12 +endif + +ifneq (,$(filter wolfssl_tls13,$(USEMODULE))) + USEMODULE += wolfcrypt_aes + USEMODULE += sock_tls +endif + +ifneq (,$(filter wolfssl_dtls,$(USEMODULE))) + USEMODULE += sock_tls +endif + +ifneq (,$(filter wolfssl_psk,$(USEMODULE))) + USEMODULE += sock_tls +endif + +ifneq (,$(filter sock_tls,$(USEMODULE))) + USEMODULE += wolfcrypt + USEMODULE += wolfcrypt_aes + USEMODULE += wolfcrypt_asn + USEMODULE += wolfcrypt_hmac + USEMODULE += wolfcrypt_md5 + USEMODULE += wolfcrypt_sha + USEMODULE += wolfcrypt_random + USEMODULE += wolfssl_internal + USEMODULE += wolfssl_wolfio + USEMODULE += wolfssl_keys + USEMODULE += wolfssl_ssl + USEMODULE += wolfssl_tls +endif + +ifneq (,$(filter wolfssl_socket,$(USEMODULE))) + USEMODULE += wolfcrypt + USEMODULE += wolfcrypt_aes + USEMODULE += wolfcrypt_asn + USEMODULE += wolfcrypt_hmac + USEMODULE += wolfcrypt_md5 + USEMODULE += wolfcrypt_sha + USEMODULE += wolfcrypt_random + USEMODULE += wolfssl_internal + USEMODULE += wolfssl_wolfio + USEMODULE += wolfssl_keys + USEMODULE += wolfssl_ssl + USEMODULE += wolfssl_tls + USEMODULE += posix_sockets + USEMODULE += posix_inet +endif + +ifneq (,$(filter wolfcrypt_random,$(USEMODULE))) + USEMODULE += random +endif diff --git a/pkg/wolfssl/Makefile.include b/pkg/wolfssl/Makefile.include new file mode 100644 index 0000000000..5bf3471bcc --- /dev/null +++ b/pkg/wolfssl/Makefile.include @@ -0,0 +1,37 @@ +CFLAGS += -DWOLFSSL_USER_SETTINGS=1 +CFLAGS += -DWOLFSSL_RIOT_OS=1 +INCLUDES += -I$(PKGDIRBASE)/../../../ +INCLUDES += -I$(PKGDIRBASE)/wolfssl +INCLUDES += -I$(RIOTBASE)/pkg/wolfssl/sock_tls +INCLUDES += -I$(RIOTBASE)/pkg/wolfssl/include + +# One current limitation is that it is not possible to build `wolfcrypt` without +# including `wolfssl`. +# It would require some changes: +# * Use a different name for the `wolfssl` implementation to differenciate from +# the package directory +# * Declare `wolfssl` a PSEUDOMODULES +# * Remove the archive in Makefile.include for packages as they could be +# PSEUDOMODULES +# `$(USEPKG:%=$(BINDIR)/%.a):` +ifneq (,$(filter wolfcrypt,$(USEMODULE))) + DIRS += $(PKGDIRBASE)/wolfssl/wolfcrypt/src +endif +ifneq (,$(filter wolfcrypt-test,$(USEMODULE))) + DIRS += $(PKGDIRBASE)/wolfssl/wolfcrypt/test +endif +ifneq (,$(filter wolfcrypt-benchmark,$(USEMODULE))) + DIRS += $(PKGDIRBASE)/wolfssl/wolfcrypt/benchmark +endif +ifneq (,$(filter wolfssl,$(USEPKG))) + DIRS += $(PKGDIRBASE)/wolfssl/src +endif +ifneq (,$(filter sock_tls,$(USEMODULE))) + DIRS += $(RIOTBASE)/pkg/wolfssl/sock_tls +endif + +# wolfcrypt implements different options using pseudomodules +PSEUDOMODULES += wolfcrypt_% + +# wolfssl implements different options using pseudomodules (ocsp, dtls, crl, etc.) +PSEUDOMODULES += wolfssl_% diff --git a/pkg/wolfssl/Makefile.wolfcrypt b/pkg/wolfssl/Makefile.wolfcrypt new file mode 100644 index 0000000000..e1d26727eb --- /dev/null +++ b/pkg/wolfssl/Makefile.wolfcrypt @@ -0,0 +1,33 @@ +MODULE = wolfcrypt + +SUBMODULES += 1 + +# Do not fail for module that do not have a file +SUBMODULES_NOFORCE = 1 + +NO_AUTO_SRC = 1 + +#-------------------------------------------------------------# +# Default CRYPTO source files # +#-------------------------------------------------------------# +SRC += error.c \ + hash.c \ + logging.c \ + wc_encrypt.c \ + wc_port.c \ + wolfmath.c + +#-------------------------------------------------------------# +# Optional CRYPTO source files, enabled by default # +#-------------------------------------------------------------# + +# Enabled by default +SRC += sha.c +SRC += sha256.c +SRC += fe_low_mem.c +SRC += ge_low_mem.c +SRC += sp_int.c +SRC += sp_c32.c + + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/wolfssl/Makefile.wolfcrypt-benchmark b/pkg/wolfssl/Makefile.wolfcrypt-benchmark new file mode 100644 index 0000000000..1ba757edaf --- /dev/null +++ b/pkg/wolfssl/Makefile.wolfcrypt-benchmark @@ -0,0 +1,8 @@ +MODULE = wolfcrypt-benchmark + +NO_AUTO_SRC = 1 + +#Add to enable wolfcrypt crypto benchmark +SRC += benchmark.c + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/wolfssl/Makefile.wolfcrypt-test b/pkg/wolfssl/Makefile.wolfcrypt-test new file mode 100644 index 0000000000..462b980024 --- /dev/null +++ b/pkg/wolfssl/Makefile.wolfcrypt-test @@ -0,0 +1,8 @@ +MODULE = wolfcrypt-test + +NO_AUTO_SRC = 1 + +#Add to enable wolfcrypt self tests +SRC += test.c + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/wolfssl/Makefile.wolfssl b/pkg/wolfssl/Makefile.wolfssl new file mode 100644 index 0000000000..e760f1c2be --- /dev/null +++ b/pkg/wolfssl/Makefile.wolfssl @@ -0,0 +1,8 @@ +MODULE = wolfssl + +NO_AUTO_SRC = 1 +SUBMODULES += 1 +SUBMODULES_NOFORCE = 1 + + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/wolfssl/doc.txt b/pkg/wolfssl/doc.txt new file mode 100644 index 0000000000..7c3e19f6da --- /dev/null +++ b/pkg/wolfssl/doc.txt @@ -0,0 +1,156 @@ +/** + * @defgroup pkg_wolfssl Embedded SSL/TLS library + * @ingroup pkg + * @ingroup sys + * @brief Provides SSL/TLS solution + * + * # Introduction + * + * This package provides an embedded SSL/TLS library specifically developed for + * memory-constrained devices. + * + * # License + * + * wolfSSL’s software is available under two distinct licensing models: + * Open Source (GPLv2) or proprietary. + * + * Open Source + * + * wolfSSL (formerly CyaSSL) offers multiple products including, but not limited + * to: + * + * wolfSSL + * wolfCrypt + * wolfMQTT + * wolfSSH + * + * These software products are free software and may be modified to + * the needs of the user as long as the user adheres to version two of the GPL + * License. The GPLv2 license can be found on the gnu.org website + * (http://www.gnu.org/licenses/old-licenses/gpl-2.0.html). + * + * + * Commercial Licensing + * + * Businesses and enterprises who wish to incorporate wolfSSL products into + * proprietary appliances or other commercial software products for + * re-distribution must license commercial versions. Commercial licenses for + * wolfSSL, yaSSL, and wolfCrypt are available. Licenses are generally issued + * for one product and include unlimited royalty-free distribution. Custom + * licensing terms are also available. + * + * Commercial licenses are also available for wolfMQTT and wolfSSH. + * Please contact licensing@wolfssl.com with inquiries. + * + * @see https://github.com/wolfssl/wolfssl.git + * + * + * wolfSSL is securing over 2 billion end points today and is one of the + * industry leading SSL/TLS/Cryptographic providers for embedded systems and the + * IoT space. wolfSSL is very excited to be working with the RIOT-OS team! + * + * You can easily take advantage of wolfSSL by using the following in your + * application Makefile: + * + * ```makefile + * USEPKG += wolfssl + * ``` + * + * Don't forget to use the wolfSSL settings header in your app. This header + * should always be included FIRST preceding any other wolfSSL headers to + * ensure the correct configuration is picked up when including other wolfSSL + * headers: + * + * ```c + * #include + * ``` + * + * FEATURES: + * + * Because wolfSSL was designed with embedded systems in mind the library is + * extremely modular. There are very few dependancies in wolfSSL Cryptographic + * library and we have chosen to setup the pkg makefile to allow for easy + * modification by developers. We chose to include the core of our library in a + * singular list and then separate out the features that a developer may or may + * not wish to use by default. Please reference the Makefile.wolfssl in + * "/pkg/wolfssl" directory. wolfSSL has chosen to enable a + * significant portion of our wolfcrypt functionality by default and provided + * informative comments to explain how a feature might be enabled/disabled. + * + * Features should be controlled with the header "user_settings.h" included with + * the package. + * On RIOT-OS, wolfSSL and wolfCrypt libraries can be configured using + * PSEUDOMODULES. After selecting the wolfSSL package via: + * + * ```makefile + * USEPKG+=wolfssl + * ``` + * + * Single ciphers, algorithms and features can be selected by including the + * associated pseudomodule, e.g.: + * + * ```makefile + * USEMODULE += wolfcrypt + * USEMODULE += wolfssl + * USEMODULE += wolfcrypt-test + * USEMODULE += wolfssl_dtls + * ``` + * + * NOTES ON TRANSPORT LAYER: + * + * wolfSSL package for RIOT-OS supports two types of socket communication: + * - GNRC UDP/IP interface (based on sock_udp) + * - generic full-POSIX socket support (based on module posix-socket) + * + * By default, GNRC support is compiled in for UDP/IP communication when the + * module `wolfssl_dtls` is selected. Ensure that the module `gnrc_sock_udp` + * is also included in the build. + * + * Alternatively, to enable full-POSIX TLS/DTLS, select the `wolfssl_socket` module by + * adding the followint to the application's Makefile: + * + * ```makefile + * USEMODULE += wolfssl_socket + * ``` + * + * Refer to the examples in the following section for more details about the API + * and the integration with the transport layer. + * + * EXAMPLES: + * + * wolfSSL has provided a few examples of using this package in the RIOT + * examples directory. To test these do any of the following: + * + * wolfSSL Test/Benchmark: + * Useful to verify that the ciphers are working properly + * on the target, and comparing performance on different + * platforms. + * + * ```makefile + * cd /RIOT/tests/wolfssl-test + * make + * ./bin/native/wolfssl-test.elf # execute native port + * ``` + * + * ED25519 signature verification demo + * Very small footprint application to demonstrate + * Ed25519 signature verification with a very small footprint + * and memory requirements + * + * ```makefile + * cd /RIOT/tests/wolfcrypt-ed25519-verify + * make + * ./bin/native/wolfcrypt-ed25519-verify.elf # execute native port + * ``` + * + * + * DTLS Client and Server Example + * DTLS example over GNRC UDP/IP stack. + * See documentation in `examples/dtls-wolfssl/README.md` + * + * QUESTIONS / CONCERNS / FEEDBACK: + * + * For any questions, concerns, or other feedback please contact + * support@wolfssl.com anytime, we are always happy to help in any way we can!! + * + */ diff --git a/pkg/wolfssl/include/user_settings.h b/pkg/wolfssl/include/user_settings.h new file mode 100644 index 0000000000..7ffec01736 --- /dev/null +++ b/pkg/wolfssl/include/user_settings.h @@ -0,0 +1,322 @@ +/* user_settings.h : custom configuration for wolfcrypt/wolfSSL */ + +#ifndef USER_SETTINGS_H +#define USER_SETTINGS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* System */ +#ifndef WOLFSSL_RIOT_OS +#define WOLFSSL_RIOT_OS 1 +#endif +#include +#define CUSTOM_RAND_GENERATE random_uint32 +#define CUSTOM_RAND_TYPE uint32_t +#define NO_WRITEV +#define NO_DEV_RANDOM +#define NO_FILESYSTEM +#define NO_WOLFSSL_MEMORY +#define NO_MAIN_DRIVER +#define NO_SIG_WRAPPER +#define NO_OLD_RNGNAME + +/* Uncomment the next two lines to enable wolfSSL debug */ +// #define DEBUG_WOLFSSL +// #define WOLFSSL_LOG_PRINTF + +/* Single precision math */ +#define WOLFSSL_SP_MATH +#define WOLFSSL_SP_SMALL +#define SP_WORD_SIZE 32 +#define WOLFSSL_SP + + + +/* GNRC support enabled if not + * using sockets + */ +#ifndef MODULE_WOLFSSL_SOCKET +#define WOLFSSL_GNRC +#define WOLFSSL_USER_IO +#else +#include +#endif + +/* Select wolfcrypt only / +wolfssl + * at compile time (via USEMODULE) + */ +#ifndef MODULE_WOLFSSL_TLS +#ifndef MODULE_WOLFSSL_TLS13 +#define WOLFCRYPT_ONLY +#else +#define NO_OLD_TLS +#define HAVE_TLS_EXTENSIONS +#define HAVE_AES_DECRYPT +#define HAVE_AESGCM +#define GCM_SMALL +#define HAVE_AESCCM +#define WOLFSSL_AES_COUNTER +#define WOLFSSL_AES_DIRECT +#endif +#else +#define HAVE_TLS_EXTENSIONS +#endif + +/* Align on 32-bit (exc. native, + * don't modify default alignment.) + */ +#ifndef BOARD_NATIVE +#define WOLFSSL_GENERAL_ALIGNMENT 4 +#endif + +/* ARM-specific optimizations */ +#ifdef CPU_ARM +#define TFM_ARM +#endif + +/* defined somewhere else */ +#ifndef __mips__ +int strncasecmp(const char *s1, const char * s2, unsigned int sz); +#endif + +#define SINGLE_THREADED + +/* Global settings */ +#define SMALL_SESSION_CACHE +#define WOLFSSL_DH_CONST +#define WORD64_AVAILABLE +#define TFM_TIMING_RESISTANT +#define USE_CERT_BUFFERS_2048 +#define NO_RC4 + +/* Modules */ +#undef WC_NO_RNG +#ifndef MODULE_WOLFCRYPT_RANDOM +#define WC_NO_RNG +#endif + +#undef WOLFSSL_DTLS +#ifdef MODULE_WOLFSSL_DTLS +#define WOLFSSL_DTLS +#endif + +#undef HAVE_FFDHE_2048 +#ifdef MODULE_WOLFCRYPT_FFDHE_2048 +#define HAVE_FFDHE_2048 +#endif + +#undef HAVE_CHACHA +#ifdef MODULE_WOLFCRYPT_CHACHA +#define HAVE_CHACHA +#endif + +#undef HAVE_POLY1305 +#ifdef MODULE_WOLFCRYPT_POLY1305 +#define HAVE_POLY1305 +#define HAVE_ONE_TIME_AUTH +#endif + +#undef HAVE_CURVE25519 +#ifdef MODULE_WOLFCRYPT_CURVE25519 +#define HAVE_CURVE25519 +#define CURVE25519_SMALL +#endif + +#undef HAVE_ED25519 +#ifdef MODULE_WOLFCRYPT_ED25519 +#define HAVE_ED25519 +#define ED25519_SMALL +#endif + +#undef NO_AES +#undef NO_CODING +#undef NO_CMAC +#ifndef MODULE_WOLFCRYPT_AES +#define NO_AES +#endif +#ifndef MODULE_WOLFCRYPT_CMAC +#define NO_CMAC +#endif +#ifndef MODULE_WOLFCRYPT_CODING +#define NO_CODING +#endif + +#ifndef MODULE_WOLFCRYPT_ASN +#define NO_ASN +#endif + +#ifndef MODULE_WOLFCRYPT_HMAC +#define NO_HMAC +#endif + +#undef NO_SHA +#ifndef MODULE_WOLFCRYPT_SHA +#define NO_SHA +#else +#define USE_SLOW_SHA +#define USE_SLOW_SHA2 +#endif + +#undef HAVE_SHA512 +#undef HAVE_SHA384 +#undef WOLFSSL_SHA384 +#undef WOLFSSL_SHA512 +#ifdef MODULE_WOLFCRYPT_SHA512 +#define HAVE_SHA384 +#define HAVE_SHA512 +#define WOLFSSL_SHA384 +#define WOLFSSL_SHA512 +#define USE_SLOW_SHA512 +#endif + +#undef WOLFSSL_SHA3 +#ifdef MODULE_WOLFCRYPT_SHA3 +#define WOLFSSL_SHA3 +#endif + +#undef HAVE_ECC +#ifdef MODULE_WOLFCRYPT_ECC +#define HAVE_ECC +#define FP_ECC +#define WOLFSSL_HAVE_SP_ECC +#define WOLFSSL_HAVE_SP_ECC +#define ECC_TIMING_RESISTANT +#define HAVE_SUPPORTED_CURVES +#endif + +#undef HAVE_BLAKE2B +#ifdef MODULE_WOLFCRYPT_BLAKE2B +#define HAVE_BLAKE2B +#endif + +#undef HAVE_CAMELLIA +#ifdef MODULE_WOLFCRYPT_CAMELLIA +#define HAVE_CAMELLIA +#endif + +#undef HAVE_IDEA +#ifdef MODULE_WOLFCRYPT_IDEA +#define HAVE_IDEA +#endif + +#undef HAVE_HC128 +#ifdef MODULE_WOLFCRYPT_HC128 +#define HAVE_HC128 +#endif + +#undef HAVE_PKCS7 +#ifdef MODULE_WOLFCRYPT_PKCS7 +#define HAVE_PKCS7 +#endif + +#undef NO_PKCS12 +#ifndef MODULE_WOLFCRYPT_PKCS12 +#define NO_PKCS12 +#endif + +#undef NO_PWDBASED +#ifndef MODULE_WOLFCRYPT_PWDBASED +#define NO_PWDBASED +#endif + +#undef WOLFSSL_STATIC_PSK +#ifdef MODULE_WOLFSSL_PSK +#define WOLFSSL_STATIC_PSK +#endif + +#undef HAVE_LIBZ +#ifdef MODULE_WOLFCRYPT_COMPRESS +#define HAVE_LIBZ +#endif + +#ifdef MODULE_WOLFCRYPT_RSA +#define HAVE_RSA +#define RSA_LOW_MEM +#define WC_RSA_BLINDING +#define WOLFSSL_STATIC_RSA +#define WOLFSSL_HAVE_SP_DH +#define WOLFSSL_HAVE_SP_RSA +#else +#define NO_RSA +#endif + +#undef NO_DES3 +#ifndef MODULE_WOLFCRYPT_DES3 +#define NO_DES3 +#endif + +#undef NO_DH +#ifndef MODULE_WOLFCRYPT_DH +#define NO_DH +#endif + +#undef NO_DSA +#ifndef MODULE_WOLFCRYPT_DSA +#define NO_DSA +#endif + +#undef WOLFSSL_MD2 +#ifdef MODULE_WOLFSSL_MD2 +#define WOLFSSL_MD2 +#endif + +#undef NO_MD4 +#ifndef MODULE_WOLFCRYPT_MD4 +#define NO_MD4 +#endif + +#undef NO_RABBIT +#ifndef MODULE_WOLFCRYPT_RABBIT +#define NO_RABBIT +#endif + +#undef NO_MD5 +#ifndef MODULE_WOLFCRYPT_MD5 +#define NO_MD5 +#endif + +#undef WOLFSSL_RIPEMD +#ifdef MODULE_WOLFCRYPT_RIPEMD +#define WOLFSSL_RIPEMD +#endif + +#undef NO_SIG_WRAPPER +#ifndef MODULE_WOLFCRYPT_SIGNATURE +#define NO_SIG_WRAPPER +#endif + +#undef HAVE_SRP +#ifdef MODULE_WOLFCRYPT_SRP +#define HAVE_SRP +#endif + +#undef HAVE_OCSP +#ifdef MODULE_WOLFSSL_OCSP +#define HAVE_OCSP +#endif + +#undef HAVE_CRL +#ifdef MODULE_WOLFSSL_CRL +#define HAVE_CRL +#endif + +#undef HAVE_TLS13 +#ifdef MODULE_WOLFSSL_TLS13 +#define HAVE_TLS13 +#define WOLFSSL_TLS13 +#define BUILD_TLS_AES_128_GCM_SHA256 +#endif + +#ifdef __cplusplus +} +#endif + +/* The following defines should prevent declaration of name-colliding "Aes" + * structure on SAML21, SAME54 platform code + */ +#define _SAML21_AES_COMPONENT_ +#define _SAME54_AES_COMPONENT_ + +#endif /* USER_SETTINGS_H */ diff --git a/pkg/wolfssl/sock_tls/Makefile b/pkg/wolfssl/sock_tls/Makefile new file mode 100644 index 0000000000..df6e8e323f --- /dev/null +++ b/pkg/wolfssl/sock_tls/Makefile @@ -0,0 +1,3 @@ +MODULE := sock_tls + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/wolfssl/sock_tls/sock_tls.c b/pkg/wolfssl/sock_tls/sock_tls.c new file mode 100644 index 0000000000..199326b139 --- /dev/null +++ b/pkg/wolfssl/sock_tls/sock_tls.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2019 Daniele Lacamera + * + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include +#include + +#include +#include +#include + +#include + +void sock_dtls_close(sock_tls_t *sk) +{ + sock_udp_close(&sk->conn.udp); +} + +void sock_dtls_set_endpoint(sock_tls_t *sk, const sock_udp_ep_t *addr) +{ + LOG(LOG_INFO, "wolfSSL: Setting peer address and port\n"); + XMEMCPY(&sk->peer_addr, addr, sizeof (sock_udp_ep_t)); +} + +int sock_dtls_create(sock_tls_t *sock, const sock_udp_ep_t *local, const sock_udp_ep_t *remote, uint16_t flags, WOLFSSL_METHOD *method) +{ + int ret; + if (!sock) + return -EINVAL; + XMEMSET(sock, 0, sizeof(sock_tls_t)); + sock->ctx = wolfSSL_CTX_new(method); + if (!sock->ctx) + return -ENOMEM; + + ret = sock_udp_create(&sock->conn.udp, local, remote, flags); + if (ret < 0) { + XFREE(sock->ctx, NULL, 0); + return ret; + } + if (remote) { + XMEMCPY(&sock->peer_addr, remote, sizeof(sock_udp_ep_t)); + } + return 0; +} + +static int tls_session_create(sock_tls_t *sk) +{ + if (!sk || !sk->ctx) + return -EINVAL; + sk->ssl = wolfSSL_new(sk->ctx); + if (sk->ssl == NULL) { + LOG(LOG_ERROR, "Error allocating ssl session\n"); + return -ENOMEM; + } + wolfSSL_SetIOReadCtx(sk->ssl, sk); + wolfSSL_SetIOWriteCtx(sk->ssl, sk); + sk->ssl->gnrcCtx = sk; + return 0; +} + +static void tls_session_destroy(sock_tls_t *sk) +{ + if (!sk || sk->ssl) + return; + wolfSSL_free(sk->ssl); +} + +int sock_dtls_session_create(sock_tls_t *sk) +{ + return tls_session_create(sk); +} + +void sock_dtls_session_destroy(sock_tls_t *sk) +{ + tls_session_destroy(sk); +} + + +#ifdef MODULE_SOCK_TCP +/* TODO */ +#endif + + + +#ifndef __mips__ +#include +int strncasecmp(const char *s1, const char * s2, unsigned int sz) +{ + unsigned int i; + for( i = 0; i < sz; i++) { + int res; + const unsigned char *us1 = (const unsigned char *)s1; + const unsigned char *us2 = (const unsigned char *)s2; + res = toupper(us1[i]) - toupper(us2[i]); + if (res != 0) + return res; + } + return 0; +} +#endif diff --git a/pkg/wolfssl/sock_tls/sock_tls.h b/pkg/wolfssl/sock_tls/sock_tls.h new file mode 100644 index 0000000000..4982cf8626 --- /dev/null +++ b/pkg/wolfssl/sock_tls/sock_tls.h @@ -0,0 +1,344 @@ +/* + * Copyright (C) 2019 Daniele Lacamera + * + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/* @defgroup module sock_tls + * @ingroup pkg_wolfssl + * @brief Sock submodule for TLS/DTLS sessions + * + * How To Use + * ---------- + * First you need to @ref including-modules "include" a module that implements + * this API in your application's Makefile. + * + * The `sock_tls` module requires the `wolfssl` package. + * + * The application's Makefile should at lease contain the following: + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {Makefile} + * + * USEPKG += wolfssl + * USEMODULE+=sock_tls + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * + * ### A Simple DTLS Server + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c} + * #include + * #include + * + * #include + * #include + * + * #include + * + * #include + * #include + * #include + * + * #define SERVER_PORT 11111 + * #define DEBUG 1 + * extern const unsigned char server_cert[788]; + * extern const unsigned char server_key[121]; + * extern unsigned int server_cert_len; + * extern unsigned int server_key_len; + * + * static sock_tls_t skv; + * static sock_tls_t *sk = &skv; + * static const char Test_dtls_string[] = "DTLS OK!"; + * + * int main(void) + * { + * char buf[64]; + * int ret; + * sock_udp_ep_t local = SOCK_IPV6_EP_ANY; + * local.port = SERVER_PORT; + * + * if (sock_dtls_create(sk, &local, NULL, 0, wolfDTLSv1_2_server_method()) != 0) { + * printf("Failed to create DTLS socket context\r\n"); + * return -1; + * } + * if (wolfSSL_CTX_use_certificate_buffer(sk->ctx, server_cert, + * server_cert_len, SSL_FILETYPE_ASN1 ) != SSL_SUCCESS) + * { + * printf("Failed to load certificate from memory.\r\n"); + * return -1; + * } + * + * if (wolfSSL_CTX_use_PrivateKey_buffer(sk->ctx, server_key, + * server_key_len, SSL_FILETYPE_ASN1 ) != SSL_SUCCESS) + * { + * printf("Failed to load private key from memory.\r\n"); + * return -1; + * } + * ret = sock_dtls_session_create(sk); + * if (ret < 0) + * { + * printf("Failed to create DTLS session (err: %s)\r\n", strerror(-ret)); + * return -1; + * } + * printf("Listening on %d\n", SERVER_PORT); + * while(1) { + * ret = wolfSSL_accept(sk->ssl); + * if (ret != SSL_SUCCESS) { + * continue; + * } + * printf("Connection accepted\r\n"); + * ret = wolfSSL_read(sk->ssl, buf, 64); + * if (ret > 0) { + * buf[ret] = (char)0; + * printf("Received '%s'\r\n", buf); + * } + * printf("Sending 'DTLS OK'...\r\n"); + * wolfSSL_write(sk->ssl, Test_dtls_string, sizeof(Test_dtls_string)); + * printf("Closing connection.\r\n"); + * sock_dtls_session_destroy(sk); + * sock_dtls_close(sk); + * break; + * } + * return 0; + * } + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Above you see a simple DTLS echo server. It is important to at least include + * @ref including-modules "include" the IPv6 module of your networking + * implementation (e.g. `gnrc_ipv6_default` for @ref net_gnrc GNRC) and at least + * one network device. + * A separate file should define the buffers used as certificate and private key, + * in the variables `server_cert`, `private_key` respectively. + * + * After including all the needed header files, we use a global object to store + * the context for incoming DTLS communication. The object contains the reference + * to the wolfSSL context, the SSL session and the underlying transport socket. + * + * For simplicity, we will refer to the address of the object in the static memory, + * through the pointer `sk`. + * + * A constant test string is used later as a reply to incoming connections. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c} + * static sock_tls_t skv; + * static sock_tls_t *sk = &skv; + * + * static const char Test_dtls_string[] = "DTLS OK!"; + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * In the same way as a normal @ref net_sock_udp "UDP socket", in order to be able to + * listen for incoming packets, we bind the `sock` by setting a local endpoint with + * a port (`11111` in this case). + * + * We then proceed to create the `sock`. It is bound to `local` and thus listens + * for UDP packets with @ref udp_hdr_t::dst_port "destination port" `12345`. + * Since we don't need any further configuration we set the flags to 0. + * The method argument determines which kind of wolfSSL context is associated to + * the socket. +* + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c} + * sock_udp_ep_t local = SOCK_IPV6_EP_ANY; + * local.port = SERVER_PORT; + * + * if (sock_dtls_create(sk, &local, NULL, 0, wolfDTLSv1_2_server_method()) != 0) { + * printf("ERROR: Unable to create DTLS sock\r\n"); + * return -1; + * } + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * By default, all sock_tls operations in a DTLS context are blocking for a + * limited amount of time, which depends on the DTLS session timeout. To modify + * the timeout, use `wolfSSL_dtls_set_timeout_init(sk->ssl)`. + * + * Certificate and private key for the server context are loaded from a previously + * initialized section in memory: + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c} + * if (wolfSSL_CTX_use_certificate_buffer(sk->ctx, server_cert, + * server_cert_len, SSL_FILETYPE_ASN1 ) != SSL_SUCCESS) + * { + * printf("Failed to load certificate from memory.\r\n"); + * return -1; + * } + * + * if (wolfSSL_CTX_use_PrivateKey_buffer(sk->ctx, server_key, + * server_key_len, SSL_FILETYPE_ASN1 ) != SSL_SUCCESS) + * { + * printf("Failed to load private key from memory.\r\n"); + * return -1; + * } + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Once the context is configured, the SSL session can be initialized. + * + * The listening sock automatically takes care of the DTLS handshake. + * When the session is established, `wolfSSL_accept()` will finally return + * `SSL_SUCCESS`. + * + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c} + * ret = sock_dtls_session_create(sk); + * if (ret < 0) + * { + * printf("Failed to create DTLS session (err: %s)\r\n", strerror(-ret)); + * return -1; + * } + * printf("Listening on %d\n", SERVER_PORT); + * while(1) { + * ret = wolfSSL_accept(sk->ssl); + * if (ret != SSL_SUCCESS) { + * continue; + * } + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * At this point, the session is established, and encrypted data can be exchanged + * using `wolfSSL_read()` and `wolfSSL_write()`: + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c} + * ret = wolfSSL_read(sk->ssl, buf, 64); + * if (ret > 0) { + * buf[ret] = (char)0; + * printf("Received '%s'\r\n", buf); + * } + * printf("Sending 'DTLS OK'...\r\n"); + * wolfSSL_write(sk->ssl, Test_dtls_string, sizeof(Test_dtls_string)); + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * The session is terminated, and the associated socket is closed. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c} + * sock_dtls_session_destroy(sk); + * sock_dtls_close(sk); + * break; + * } + * return 0; + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + */ + + + +#include +#include +#include + +#include +#include + +#ifndef SOCK_TLS_H +#define SOCK_TLS_H +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Creates a new DTLS sock object. + * + * @pre `(sock != NULL)` + * @pre `(remote == NULL) || (remote->port != 0)` + * + * @param[out] sock The resulting sock object. + * @param[in] local Local end point for the sock object. + * May be NULL. + * sock_udp_ep_t::netif must either be + * @ref SOCK_ADDR_ANY_NETIF or equal to + * sock_udp_ep_t::netif of @p remote if `remote != NULL`. + * If NULL @ref sock_udp_send() may bind implicitly. + * sock_udp_ep_t::port may also be 0 to bind the `sock` to + * an ephemeral port. + * @param[in] remote Remote end point for the sock object. + * May be `NULL` but then the `remote` parameter of + * @ref sock_udp_send() may not be `NULL` or it will + * always error with return value -ENOTCONN. + * sock_udp_ep_t::port must not be 0 if `remote != NULL`. + * sock_udp_ep_t::netif must either be + * @ref SOCK_ADDR_ANY_NETIF or equal to sock_udp_ep_t::netif + * of @p local if `local != NULL`. + * @param[in] flags Flags for the sock object. See also + * [sock flags](@ref net_sock_flags). + * May be 0. + * @param[in] method Defines the SSL or TLS protocol for the client or server to use. + * There are several options for selecting the desired protocol. + * wolfSSL currently supports DTLS 1.0, and DTLS 1.2. Each of these + * protocols have a corresponding function that can be used as last + * argument to `sock_dtls_create`. The possible client and server + * protocol options are: `wolfDTLSv1_client_method()`, `wolfDTLSv1_server_method()`, + * `wolfDTLSv1_2_client_method()` and `wolfDTLSv1_server_method`. + * + * @return 0 on success. + * @return -EADDRINUSE, if `local != NULL` and @p local is already used + * elsewhere or if `local->port == 0` but the pool of ephemeral ports + * is depleted + * @return -EAFNOSUPPORT, if `local != NULL` or `remote != NULL` and + * sock_udp_ep_t::family of @p local or @p remote is not supported. + * @return -EINVAL, if sock_udp_ep_t::addr of @p remote is an invalid address. + * @return -EINVAL, if sock_udp_ep_t::netif of @p local or @p remote are not a + * valid interfaces or contradict each other (i.e. + * `(local->netif != remote->netif) && + * ((local->netif != SOCK_ADDR_ANY_NETIF) || + * (remote->netif != SOCK_ADDR_ANY_NETIF))` if neither is `NULL`). + * @return -ENOMEM, if not enough resources can be provided for `sock` to be + * created. + */ +int sock_dtls_create(sock_tls_t *sock, const sock_udp_ep_t *local, const sock_udp_ep_t *remote, uint16_t flags, WOLFSSL_METHOD *method); + +/** + * @brief Sets the endpoint address for the remote DTLS peer associated to this sock object + * + * @pre `(sk != NULL)` + * @pre `(addr != NULL)` + * + * @param[in] sk The resulting sock object. + * @param[in] addr Remote end point for the DTLS session. + * + */ +void sock_dtls_set_endpoint(sock_tls_t *sk, const sock_udp_ep_t *addr); + +/** + * @brief Creates a new DTLS session from an existing `sock_tls_t` object. + * + * @pre `(sk != NULL)` + * + * @param[in] sk The sock object previously created using @ref sock_dtls_create + * + * @return 0 on success. + * @return -EINVAL, if @sock is null or the SSL context is not initialized yet. + * @return -ENOMEM, if not enough resources can be provided for the session to be + * created + */ +int sock_dtls_session_create(sock_tls_t *sk); + +/** + * @brief Destroys the DTLS session associated to the sock object. + * + * @pre `(sk != NULL)` + * + * @param[in] sk The sock object containing the session to destroy. + * + */ +void sock_dtls_session_destroy(sock_tls_t *sk); + +/** + * @brief Closes the socket connection associated to the DTLS session. + * + * @pre `(sk != NULL)` + * + * @param[in] sk The sock object containing the UDP socket to close. + * + */ +void sock_dtls_close(sock_tls_t *sk); + + +#ifdef MODULE_SOCK_TCP +# error Only support for UDP/IP provided via GNRC stack. +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SOCK_TLS_H */ diff --git a/tests/pkg_wolfcrypt-ed25519-verify/Makefile b/tests/pkg_wolfcrypt-ed25519-verify/Makefile new file mode 100644 index 0000000000..c6a7feaf90 --- /dev/null +++ b/tests/pkg_wolfcrypt-ed25519-verify/Makefile @@ -0,0 +1,34 @@ +include ../Makefile.tests_common + +# If no BOARD is found in the environment, use this default: +BOARD ?= native + +# Only 32-bit targets +BOARD_BLACKLIST := arduino-duemilanove arduino-leonardo \ + arduino-mega2560 arduino-nano \ + arduino-uno chronos esp8266-esp-12x esp8266-olimex-mod \ + esp8266-sparkfun-thing jiminy-mega256rfr2 mega-xplained \ + msb-430 msb-430h telosb waspmote-pro \ + wsn430-v1_3b wsn430-v1_4 z1 + +# This has to be the absolute path to the RIOT base directory: +RIOTBASE ?= $(CURDIR)/../.. + +# Comment this out to disable code in RIOT that does safety checking +# which is not needed in a production environment but helps in the +# development process: +DEVELHELP ?= 1 + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + +# Ensure there is enough stack space +CFLAGS += -DTHREAD_STACKSIZE_MAIN=THREAD_STACKSIZE_LARGE + +CFLAGS+=-DNO_ED25519_SIGN -DNO_ED25519_KEY_EXPORT + +USEPKG +=wolfssl +USEMODULE += wolfcrypt +USEMODULE += wolfcrypt_ed25519 + +include $(RIOTBASE)/Makefile.include diff --git a/tests/pkg_wolfcrypt-ed25519-verify/README.md b/tests/pkg_wolfcrypt-ed25519-verify/README.md new file mode 100644 index 0000000000..926379b8da --- /dev/null +++ b/tests/pkg_wolfcrypt-ed25519-verify/README.md @@ -0,0 +1,16 @@ +# wolfCrypt Ed25519 verify routine test + +This is a demo of a signature verification using wolfCrypt. + +wolfCrypt is part of [wolfSSL](https://www.wolfss.com) which provides several different cryptographic services. + +In this test, a text message is signed using Edwards-curve digital signature algorithm, +using the Ed25519 signature scheme. + +## How it works + +The message and its signature are hardcoded in the example. To create a new +signed message, you may use the host-application `ed25519_sign_msg` under `tools/`, +which generates a new EdDSA key pair, and produces a signature for the test message. + +The demo verifies the authenticity of the message via `wc_ed25519_verify_msg`. diff --git a/tests/pkg_wolfcrypt-ed25519-verify/main.c b/tests/pkg_wolfcrypt-ed25519-verify/main.c new file mode 100644 index 0000000000..a00fa4f17a --- /dev/null +++ b/tests/pkg_wolfcrypt-ed25519-verify/main.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2019 Daniele Lacamera + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + * + */ + +/** + * @ingroup examples + * @{ + * + * @file + * @brief ed25519 signature verification application + * + * @author Daniele Lacamera + * + * @} + */ + +#include +#include +#include "log.h" + +const uint8_t ed_public_key[ED25519_KEY_SIZE] = { + 0x9A, 0xBC, 0xA2, 0xE2, 0x4D, 0x19, 0x9E, 0x02, + 0x72, 0x69, 0x19, 0xE1, 0x05, 0x39, 0x3A, 0x08, + 0xC9, 0x9C, 0xDD, 0xA9, 0x28, 0x45, 0x8B, 0x37, + 0x9E, 0xCA, 0x20, 0x02, 0xBC, 0x7A, 0x2E, 0xC2 +}; + +const uint8_t msg[] = "Hello World!"; + +const uint8_t msg_signature[ED25519_SIG_SIZE] = { + 0x8A, 0xD3, 0xEA, 0x8F, 0x08, 0x8B, 0x8C, 0x41, + 0x61, 0x36, 0x51, 0xF4, 0x49, 0x6E, 0xD2, 0xCB, + 0xD6, 0xAC, 0x7B, 0x61, 0xD8, 0x3B, 0xE0, 0x1C, + 0xA7, 0xED, 0x72, 0x33, 0xA3, 0xB4, 0xE7, 0xBA, + 0x90, 0x47, 0xC9, 0xAE, 0x48, 0x48, 0x4A, 0x78, + 0x46, 0x63, 0x25, 0x44, 0xA5, 0x82, 0x0F, 0x4A, + 0x9A, 0x5A, 0x0E, 0x3F, 0xF5, 0xB1, 0x97, 0xAD, + 0xB5, 0x48, 0x26, 0x45, 0xD6, 0xC7, 0x00, 0x06 +}; + + +int main(void) +{ + int stat; + int ret; + ed25519_key key; + LOG(LOG_INFO, "You are running RIOT on a(n) %s board.\n", RIOT_BOARD); + LOG(LOG_INFO, "This board features a(n) %s MCU.\n", RIOT_MCU); + wc_ed25519_init(&key); + LOG(LOG_INFO, "Starting ed25519 test."); + + ret = wc_ed25519_import_public(ed_public_key, ED25519_KEY_SIZE, &key); + if (ret != 0) { + LOG(LOG_ERROR, "Error importing public key for signature verification (%d)\n", ret); + return 1; + } + if ((wc_ed25519_verify_msg(msg_signature, ED25519_SIG_SIZE, msg, 12, &stat, &key) < 0) || (stat == 0)) { + LOG(LOG_WARNING, "The signature is not valid!\n"); + } else { + LOG(LOG_INFO, "The signature is valid!\n"); + } + + return 0; +} diff --git a/tests/pkg_wolfcrypt-ed25519-verify/tools/Makefile b/tests/pkg_wolfcrypt-ed25519-verify/tools/Makefile new file mode 100644 index 0000000000..5de7fe1490 --- /dev/null +++ b/tests/pkg_wolfcrypt-ed25519-verify/tools/Makefile @@ -0,0 +1,8 @@ +all: ed25519_sign_msg + + +ed25519_sign_msg: ed25519_sign_msg.c + gcc -o $@ $^ -lwolfssl -DHAVE_ED25519 -DWOLFCRYPT_ONLY -DTFM_TIMING_RESISTANT -DNO_RSA -DECC_TIMING_RESISTANT + +clean: + @rm -f ed25519_sign_msg diff --git a/tests/pkg_wolfcrypt-ed25519-verify/tools/ed25519_sign_msg.c b/tests/pkg_wolfcrypt-ed25519-verify/tools/ed25519_sign_msg.c new file mode 100644 index 0000000000..7c54e6e634 --- /dev/null +++ b/tests/pkg_wolfcrypt-ed25519-verify/tools/ed25519_sign_msg.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2019 Daniele Lacamera + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + * + */ +#include +#include + +#include +#include + +#include "od.h" + +void print_key(void *key_in) +{ + uint8_t * key = key_in; + od_hex_dump(key, ED25519_KEY_SIZE, 8); +} + +void print_sig(void *sig_in) +{ + uint8_t * sig = sig_in; + od_hex_dump(sig, ED25519_SIG_SIZE, 8); +} + + +int main(void) +{ + uint8_t priv[ED25519_KEY_SIZE], pub[ED25519_KEY_SIZE]; + uint8_t sig[ED25519_SIG_SIZE]; + uint32_t outlen; + RNG rng; + ed25519_key key; + + wc_ed25519_init(&key); + wc_InitRng(&rng); + if (wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key) != 0) { + LOG(LOG_ERROR, "Failed to create ED25519 key!\n"); + exit(1); + } + + outlen = ED25519_KEY_SIZE; + wc_ed25519_export_private_only(&key, priv, &outlen); + printf("const uint8_t ed_private_key[ED25519_KEY_SIZE] = {\n"); + print_key(priv); + printf("};\n\n"); + + outlen = ED25519_KEY_SIZE; + wc_ed25519_export_public(&key, pub, &outlen); + printf("const uint8_t ed_public_key[ED25519_KEY_SIZE] = {\n"); + print_key(pub); + printf("};\n\n"); + + printf("const uint8_t msg[] = \"Hello World!\";\n\n"); + printf("const uint8_t msg_signature[ED25519_SIG_SIZE] = {\n"); + outlen = ED25519_SIG_SIZE; + wc_ed25519_sign_msg("Hello World!", 12, sig, &outlen, &key); + print_sig(sig); + printf("};\n\n"); + exit(0); +} diff --git a/tests/pkg_wolfssl/Makefile b/tests/pkg_wolfssl/Makefile new file mode 100644 index 0000000000..354a2a5abf --- /dev/null +++ b/tests/pkg_wolfssl/Makefile @@ -0,0 +1,57 @@ +include ../Makefile.tests_common + +# If no BOARD is found in the environment, use this default: +BOARD ?= native + +# Only 32-bit targets +BOARD_BLACKLIST := arduino-duemilanove arduino-leonardo \ + arduino-mega2560 arduino-nano \ + arduino-uno chronos esp8266-esp-12x esp8266-olimex-mod \ + esp8266-sparkfun-thing jiminy-mega256rfr2 mega-xplained \ + msb-430 msb-430h telosb waspmote-pro \ + wsn430-v1_3b wsn430-v1_4 z1 + +# +# If the test fails to run on a target, disable the algorithms +# that you do not plan to use, by removing the associated wolfcrypt_* modules +# from USEMODULE list below. +# +# You may be able to remove your target from the list below by selecting a +# smaller set of modules. +# +# Targets not included in the BOARD_INSUFFICIENT_MEMORY are capable of +# running all the benchmarks selected by default. +# +BOARD_INSUFFICIENT_MEMORY := nucleo-f042k6 stm32f0discovery nucleo-f334r8 \ + i-nucleo-lrwan1 nucleo-f302r8 nucleo-l053r8 saml11-xpro \ + nucleo-l031k6 bluepill stm32l0538-disco saml10-xpro \ + nucleo-f030r8 nucleo-f031k6 nucleo-f303k8 blackpill + +# This has to be the absolute path to the RIOT base directory: +RIOTBASE ?= $(CURDIR)/../.. + +# This is an optimized stack value based on testing, if you observe +# a segmentation fault please increase this stack size. +CFLAGS += -DTHREAD_STACKSIZE_MAIN=2*THREAD_STACKSIZE_LARGE + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + + +USEPKG += wolfssl +USEMODULE += wolfcrypt wolfcrypt-test wolfcrypt_sha512 wolfcrypt_curve25519 \ + wolfcrypt_ed25519 wolfcrypt_chacha wolfcrypt_poly1305 wolfcrypt_aes \ + wolfcrypt_ecc wolfcrypt_asn wolfcrypt_random + +# Uncomment the following line to enable RSA tests +# (e.g. when enough resources are available on platform) +#USEMODULE += wolfcrypt_rsa wolfcrypt_dh + +# Comment the following line to disable full-benchmark test +USEMODULE += wolfcrypt-benchmark + +ifneq ($(BOARD),native) + CFLAGS += -DBENCH_EMBEDDED +endif + +include $(RIOTBASE)/Makefile.include diff --git a/tests/pkg_wolfssl/README.md b/tests/pkg_wolfssl/README.md new file mode 100644 index 0000000000..6379ebb1b1 --- /dev/null +++ b/tests/pkg_wolfssl/README.md @@ -0,0 +1,21 @@ +# wolfssl tests and benchmarks + +This test can be used to validate the usability and performance of a wolfcrypt/wolfssl +port to a specific target. + +## Compile options + +Specific modules can be enabled/disabled using the `USEMODULE` variable in `Makefile`. + +To disable full-benchmark test, comment out the line `USEMODULE += wolfssl-benchmarks`. + +## Modules vs. Resources + +This test tool can be used to benchmark single pseudo-modules in the wolfSSL package, +on the selected target. + +The default `BOARD_INSUFFICIENT_MEMORY` list provided in [Makefile](Makefile) excludes +all the targets that are unable to run the full test. Targets included in this list +may still be able to run a build with a reduced set of algorithms compiled in. + +To enable/disable single modules to include in the build, see the `USEMODULE` list. diff --git a/tests/pkg_wolfssl/main.c b/tests/pkg_wolfssl/main.c new file mode 100644 index 0000000000..6b72a94434 --- /dev/null +++ b/tests/pkg_wolfssl/main.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2019 Kaleb J. Himes, Daniele Lacamera + * + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + + +/** + * @ingroup examples + * @{ + * + * @file + * @brief wolfSSL cryptographic library test + * + * @author Kaleb J. Himes + * Daniele Lacamera + * + * @} + */ + +#include +#include "xtimer.h" +#include "log.h" + +#include +#include +#ifdef MODULE_WOLFCRYPT_BENCHMARK +#include +#endif + +int main(void) +{ + LOG(LOG_INFO, "wolfSSL Crypto Test!"); + /* Wait to work around a failing tests + * on platforms that don't have RTC synchronized + */ + xtimer_sleep(1); + wolfcrypt_test(NULL); +#ifdef MODULE_WOLFCRYPT_BENCHMARK + LOG(LOG_INFO, "wolfSSL Benchmark!"); + benchmark_test(NULL); +#endif + return 0; +}