Skip to content

Commit

Permalink
add example of how to use HPKE with all options (#356)
Browse files Browse the repository at this point in the history
* add example of how to use HPKE with all options

* add example of how to use ech with a public server run by cloudflare

* move ech example to tls directory, update hpke instructions

* update client-ech based on pr comments

* update ech test to handle read error

* update hpke_test to match changed function signature

* add root CA cert for ech-client example, fix

various problems based on pr comments

* clear out variable for example

* remove unused variable
  • Loading branch information
jpbland1 authored Jul 10, 2023
1 parent 452ac9e commit f155379
Show file tree
Hide file tree
Showing 7 changed files with 514 additions and 3 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,11 @@ android/wolfssljni-ndk-sample/proguard-project.txt
/tls/server-tls-uart
/tls/server-tls-verifycallback
/tls/server-tls-writedup
/tls/client-ech
/tls/client-ech-local
/tls/server-ech-local



crypto/3des/3des-file-encrypt
crypto/aes/aes-file-encrypt
crypto/aes/aescfb-file-encrypt
Expand Down Expand Up @@ -238,6 +238,7 @@ pk/ed448/ed448_pub
pk/ed448/ed448_keys
pk/ed448/*.der
pk/curve25519/curve25519_test
pk/hpke/hpke_test

embedded/tls-client-server
embedded/tls-server-size
Expand Down
75 changes: 75 additions & 0 deletions certs/ech-client-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
-----BEGIN CERTIFICATE-----
MIIFTDCCBPKgAwIBAgIQA5JQzuqRJy3ljWStInKQTjAKBggqhkjOPQQDAjBKMQsw
CQYDVQQGEwJVUzEZMBcGA1UEChMQQ2xvdWRmbGFyZSwgSW5jLjEgMB4GA1UEAxMX
Q2xvdWRmbGFyZSBJbmMgRUNDIENBLTMwHhcNMjMwMzA0MDAwMDAwWhcNMjQwMzAz
MjM1OTU5WjB1MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQG
A1UEBxMNU2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQQ2xvdWRmbGFyZSwgSW5jLjEe
MBwGA1UEAxMVc25pLmNsb3VkZmxhcmVzc2wuY29tMFkwEwYHKoZIzj0CAQYIKoZI
zj0DAQcDQgAE1RXa9mRvotUaWVPtrpuTGJGAawyYYNRRkK2czd3xEadvstkDYygE
vE+xcpZFPPZQDkBlAAfvv8j2PNJ6f1nRN6OCA40wggOJMB8GA1UdIwQYMBaAFKXO
N+rrsHUOlGeItEX62SQQh5YfMB0GA1UdDgQWBBRekDZj95YFBGStBKQhAaqPvUhb
AzBQBgNVHREESTBHghVzbmkuY2xvdWRmbGFyZXNzbC5jb22CFWNyeXB0by5jbG91
ZGZsYXJlLmNvbYIXKi5jcnlwdG8uY2xvdWRmbGFyZS5jb20wDgYDVR0PAQH/BAQD
AgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB7BgNVHR8EdDByMDeg
NaAzhjFodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vQ2xvdWRmbGFyZUluY0VDQ0NB
LTMuY3JsMDegNaAzhjFodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vQ2xvdWRmbGFy
ZUluY0VDQ0NBLTMuY3JsMD4GA1UdIAQ3MDUwMwYGZ4EMAQICMCkwJwYIKwYBBQUH
AgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzB2BggrBgEFBQcBAQRqMGgw
JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBABggrBgEFBQcw
AoY0aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Nsb3VkZmxhcmVJbmNFQ0ND
QS0zLmNydDAMBgNVHRMBAf8EAjAAMIIBgQYKKwYBBAHWeQIEAgSCAXEEggFtAWsA
dwDuzdBk1dsazsVct520zROiModGfLzs3sNRSFlGcR+1mwAAAYaqF9guAAAEAwBI
MEYCIQCiv+PHjCl3yCBIN1geIV6nM8JVsdMDz+bi3fC0c5iSAAIhAN1bPyq66wKn
kXI9P85jRI++sCieQ8zS4KBN/yL19DsfAHcAc9meiRtMlnigIH1HneayxhzQUV5x
GSqMa4AQesF3crUAAAGGqhfYmwAABAMASDBGAiEA/rhcMmQfwxP2VpbyYpFPu5Sx
n/0Jc+/PMDSRqpst6QYCIQCuaV7aGhmR/PbE0SyQ5Y81IUPew23t5cWgQZIDLddU
GgB3AEiw42vapkc0D+VqAvqdMOscUgHLVt0sgdm7v6s52IRzAAABhqoX2GoAAAQD
AEgwRgIhAI58QAtsPkKun97n+4/gpHNqUQrC9GIyxzTTeu1quBvSAiEA1t0uZKdn
6KO27mCPHjtR8DUkhE27U2vhUICyuJGgVokwCgYIKoZIzj0EAwIDSAAwRQIhAPdp
FGP8NBnFfOe0w0vRmNwRxujz2eXnMk2LrPKqUavGAiANK5eY+3XClhMvDTTJkhzh
PEAwQeEKtlCRDESaSxItJw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDzTCCArWgAwIBAgIQCjeHZF5ftIwiTv0b7RQMPDANBgkqhkiG9w0BAQsFADBa
MQswCQYDVQQGEwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJl
clRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTIw
MDEyNzEyNDgwOFoXDTI0MTIzMTIzNTk1OVowSjELMAkGA1UEBhMCVVMxGTAXBgNV
BAoTEENsb3VkZmxhcmUsIEluYy4xIDAeBgNVBAMTF0Nsb3VkZmxhcmUgSW5jIEVD
QyBDQS0zMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEua1NZpkUC0bsH4HRKlAe
nQMVLzQSfS2WuIg4m4Vfj7+7Te9hRsTJc9QkT+DuHM5ss1FxL2ruTAUJd9NyYqSb
16OCAWgwggFkMB0GA1UdDgQWBBSlzjfq67B1DpRniLRF+tkkEIeWHzAfBgNVHSME
GDAWgBTlnVkwgkdYzKz6CFQ2hns6tQRN8DAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0l
BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8CAQAwNAYI
KwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j
b20wOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL09t
bmlyb290MjAyNS5jcmwwbQYDVR0gBGYwZDA3BglghkgBhv1sAQEwKjAoBggrBgEF
BQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzALBglghkgBhv1sAQIw
CAYGZ4EMAQIBMAgGBmeBDAECAjAIBgZngQwBAgMwDQYJKoZIhvcNAQELBQADggEB
AAUkHd0bsCrrmNaF4zlNXmtXnYJX/OvoMaJXkGUFvhZEOFp3ArnPEELG4ZKk40Un
+ABHLGioVplTVI+tnkDB0A+21w0LOEhsUCxJkAZbZB2LzEgwLt4I4ptJIsCSDBFe
lpKU1fwg3FZs5ZKTv3ocwDfjhUkV+ivhdDkYD7fa86JXWGBPzI6UAPxGezQxPk1H
goE6y/SJXQ7vTQ1unBuCJN0yJV0ReFEQPaA1IwQvZW+cwdFD19Ae8zFnWSfda9J1
CZMRJCQUzym+5iPDuI9yP+kHyCREU3qzuWFloUwOxkgAyXVjBYdwRVKD05WdRerw
6DEdfgkfCv4+3ao8XnTSrLE=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----
12 changes: 12 additions & 0 deletions pk/hpke/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CC=gcc
LIB_PATH=/usr/local
CFLAGS= -I$(LIB_PATH)/include -Wall
LIBS= -L$(LIB_PATH)/lib -lwolfssl

hpke_test: hpke_test.o
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)

.PHONY: clean

clean:
rm -f *.o hpke_test
9 changes: 9 additions & 0 deletions pk/hpke/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# HPKE Example with all supported options

To build wolfSSL for this example run `./configure --enable-hpke --enable-aesgcm --enable-curve25519 --enable-ecc && make && sudo make install`

```sh
make
./hpke_test
HPKE test success
```
163 changes: 163 additions & 0 deletions pk/hpke/hpke_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/* hpke_test.c
*
* Copyright (C) 2022 wolfSSL Inc.
*
* This file is part of wolfSSL. (formerly known as CyaSSL)
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/hpke.h>
#include <wolfssl/wolfcrypt/random.h>
#include <wolfssl/wolfcrypt/error-crypt.h>

#if defined(HAVE_HPKE) && (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \
defined(HAVE_AESGCM)
int test_hpke(Hpke* hpke)
{
int ret = 0;
int rngRet = 0;
WC_RNG rng[1];
const char* start_text = "this is a test";
const char* info_text = "info";
const char* aad_text = "aad";
byte ciphertext[MAX_HPKE_LABEL_SZ];
byte plaintext[MAX_HPKE_LABEL_SZ];
void* receiverKey = NULL;
void* ephemeralKey = NULL;
byte pubKey[HPKE_Npk_MAX]; /* public key */
word16 pubKeySz = (word16)sizeof(pubKey);

rngRet = ret = wc_InitRng(rng);

if (ret != 0)
return ret;

/* generate the keys */
if (ret == 0)
ret = wc_HpkeGenerateKeyPair(hpke, &ephemeralKey, rng);

if (ret == 0)
ret = wc_HpkeGenerateKeyPair(hpke, &receiverKey, rng);

/* seal */
if (ret == 0)
ret = wc_HpkeSealBase(hpke, ephemeralKey, receiverKey,
(byte*)info_text, (word32)XSTRLEN(info_text),
(byte*)aad_text, (word32)XSTRLEN(aad_text),
(byte*)start_text, (word32)XSTRLEN(start_text),
ciphertext);

/* export ephemeral key */
if (ret == 0)
ret = wc_HpkeSerializePublicKey(hpke, ephemeralKey, pubKey, &pubKeySz);

/* open with exported ephemeral key */
if (ret == 0)
ret = wc_HpkeOpenBase(hpke, receiverKey, pubKey, pubKeySz,
(byte*)info_text, (word32)XSTRLEN(info_text),
(byte*)aad_text, (word32)XSTRLEN(aad_text),
ciphertext, (word32)XSTRLEN(start_text),
plaintext);

if (ret == 0)
ret = XMEMCMP(plaintext, start_text, XSTRLEN(start_text));

if (ephemeralKey != NULL)
wc_HpkeFreeKey(hpke, hpke->kem, ephemeralKey, NULL);

if (receiverKey != NULL)
wc_HpkeFreeKey(hpke, hpke->kem, receiverKey, NULL);

if (rngRet == 0)
wc_FreeRng(rng);

return ret;
}

int main(void)
{
int ret = 0;
Hpke hpke[1];

#if defined(HAVE_ECC)
/* p256 */
ret = wc_HpkeInit(hpke, DHKEM_P256_HKDF_SHA256, HKDF_SHA256,
HPKE_AES_128_GCM, NULL);

if (ret != 0)
goto fail;

ret = test_hpke(hpke);

if (ret != 0)
goto fail;

/* p384 */
ret = wc_HpkeInit(hpke, DHKEM_P384_HKDF_SHA384, HKDF_SHA384,
HPKE_AES_128_GCM, NULL);

if (ret != 0)
goto fail;

ret = test_hpke(hpke);

if (ret != 0)
goto fail;

/* p521 */
ret = wc_HpkeInit(hpke, DHKEM_P521_HKDF_SHA512, HKDF_SHA512,
HPKE_AES_128_GCM, NULL);

if (ret != 0)
goto fail;

ret = test_hpke(hpke);

if (ret != 0)
goto fail;
#endif

#if defined(HAVE_CURVE25519)
/* test with curve25519 and aes256 */
ret = wc_HpkeInit(hpke, DHKEM_X25519_HKDF_SHA256, HKDF_SHA256,
HPKE_AES_256_GCM, NULL);

if (ret != 0)
goto fail;

ret = test_hpke(hpke);

if (ret != 0)
goto fail;
#endif

printf("HPKE test success\n");

return ret;

fail:
printf("HPKE test error %d: %s\n", ret, wc_GetErrorString(ret));
/* x448 and chacha20 are unimplemented */
return 1;
}
#else
int main(void)
{
printf("Please build wolfssl with ./configure --enable-hpke --enable-aesgcm --enable-curve25519 --enable-ecc\n");
return 0;
}
#endif
47 changes: 45 additions & 2 deletions tls/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,18 @@ into.
2. [Client](#client-tls)
3. [Running](#run-tls)
4. [Using callbacks](#callback)
5. [Using callbacks](#callback)
1. [Running](#run-callback)
4. [Using ECC](#ecc)
6. [Using ECC](#ecc)
1. [Server](#server-ecc)
2. [Client](#client-ecc)
3. [Running](#run-ecc)
6. [Encrypted Client Hello](#ech)
## <a name="run">Running these examples</a>
Expand Down Expand Up @@ -1335,6 +1337,47 @@ To generate your own cert text, see the [DER to C script](https://github.com/wol

<br />

## <a name="ech">Encrypted Client Hello</a>

Encrypted Client Hello (ECH) encrypts sensitive fields in the client hello step of the TLS handshake. The client-ech example connects to a cloudflare server that is setup to test different TLS options including ECH. To build wolfSSL for this ech example run `./configure --enable-ech && make && sudo make install`.

This test is successful if the cloudflare http response shows that `sni=encrypted`.

```sh
make
./client-ech
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Cache-Control: no-cache
Cf-Ray: 77c3e3e937c6b08e-ATL
Content-Type: text/plain
Expires: Thu, 01 Jan 1970 00:00:01 GMT
Server: cloudflare
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Date: Mon, 19 Dec 2022 23:24:11 GMT
Transfer-Encoding: chunked

106
fl=507f46
h=crypto.cloudflare.com
ip=173.93.184.37
ts=1671492251.082
visit_scheme=https
uag=Mozilla/5.0 (X11; Linux x86_64; rv:105.0) Gecko/20100101 Firefox/105.0
colo=ATL
sliver=none
http=http/1.1
loc=US
tls=TLSv1.3
sni=encrypted
warp=off
gateway=off
kex=P-256

0
```

## Support

Please contact wolfSSL at [email protected] with any questions, bug fixes,
Expand Down
Loading

0 comments on commit f155379

Please sign in to comment.