Closed ReverseControl closed 4 years ago
For TLS 1.3, the OQS key-exchange algorithms only pretend to be elliptic curves in the ssl
layer, so that an algorithm can be negotiated using the supported_groups
and key_share
TLS 1.3 extensions. They haven't been added to the EC API since they aren't really elliptic curves, and cannot be manipulated as such.
Thus, you should be able to specify a PQ key-exchange by passing an OQS algorithm name to an option/directive through which an EC curve/group can be named. This option will vary based on the application, but, for example, to use frodo640aes
:
1) In OpenSSL s_client
, you can pass the -curves frodo640aes
option. This will instruct s_client
to allow only frodo640aes
for key-exchange.
2) In OpenSSL s_server
: You can again pass the -curves frodo640aes
option. Again, this means s_server
will allow only frodo640aes
for key-exchange.
3) In nginx
: You can specify ssl_ecdh_curve frodo640aes
in the nginx.conf
file (as seen here). nginx
will then allow only frodo640aes
for key-exchange.
4) In httpd
: You can specify SSLOpenSSLConfCmd Curves frodo640aes
in the httpd-ssl.conf
file (as seen here)
4) In OpenVPN, after consulting this page, I believe the ecdh-curve frodo640aes
option should do the trick. I have not tried it however.
Now, if, for example, you want to support both frodo640aes
and kyber512
, and no more, you can replace frodo640aes
above with frodo640aes:kyber512
. The "Key Exchange" section here gives a full list of the OQS key-exchange algorithm names you can specify.
N.B: OpenSSL 1.1.1 has implementations of both the TLS 1.2 and TLS 1.3 protocols, and it is in TLS 1.2 that "ciphersuite" refers to "signature algorithm + key exchange method + symmetric authenticated encryption scheme". In OQS-OpenSSL 1.1.1, we have added post-quantum key-exchange algorithms to the TLS 1.3 protocol only.
I tested with OpenVPN, it does not work. No Quantum KEMs/KEXs "curves" are recognized. The server uses the below curves as expected, I tested, but with "kyber512" and "frodo640aes" as per your example I get:
openvpn --ecdh-curve kyber512 --config openvpn.conf
Thu Mar 5 22:54:42 2020 OpenVPN 2.4.8 x86_64-pc-linux-musl [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [MH/PKTINFO] [AEAD] built on Mar 4 2020
Thu Mar 5 22:54:42 2020 library versions: OpenSSL 1.1.1d 10 Sep 2019, LZO 2.10
Thu Mar 5 22:54:42 2020 Failed to use supplied curve (kyber512), using secp384r1 instead.
Thu Mar 5 22:54:42 2020 ECDH curve secp384r1 added
The function that get's called in OpenVPN to handle the ecdh-curve parameter uses OpenSSL code, but apparently is not able to find the curves nid by name . See below:
EDIT 1: I found the problem:
tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name)
void
tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name )
{
#ifndef OPENSSL_NO_EC
int nid = NID_undef;
EC_KEY *ecdh = NULL;
const char *sname = NULL;
/* Generate a new ECDH key for each SSL session (for non-ephemeral ECDH) */
SSL_CTX_set_options(ctx->ctx, SSL_OP_SINGLE_ECDH_USE);
if (curve_name != NULL)
{
/* Use user supplied curve if given */
msg(D_TLS_DEBUG, "Using user specified ECDH curve (%s)", curve_name);
nid = OBJ_sn2nid(curve_name);
}
else
{
...stuff we neve execute...
}
/* Translate NID back to name , just for kicks */
sname = OBJ_nid2sn(nid);
if (sname == NULL)
{
sname = "(Unknown)";
}
/* Create new EC key and set as ECDH key */
if (NID_undef == nid || NULL == (ecdh = EC_KEY_new_by_curve_name(nid)))
{
/* Creating key failed, fall back on sane default */
ecdh = EC_KEY_new_by_curve_name(NID_secp384r1);
const char *source = (NULL == curve_name) ?
"extract curve from certificate" : "use supplied curve";
msg(D_TLS_DEBUG_LOW,
"Failed to %s (%s), using secp384r1 instead.", source, sname);
sname = OBJ_nid2sn(NID_secp384r1);
}
if (!SSL_CTX_set_tmp_ecdh(ctx->ctx, ecdh))
{
crypto_msg(M_FATAL, "SSL_CTX_set_tmp_ecdh: cannot add curve");
}
msg(D_TLS_DEBUG_LOW, "ECDH curve %s added", sname);
EC_KEY_free(ecdh);
#else /* ifndef OPENSSL_NO_EC */
msg(D_LOW, "Your OpenSSL library was built without elliptic curve support."
" Skipping ECDH parameter loading.");
#endif /* OPENSSL_NO_EC */
}
EC_KEY_new_by_curve_name(NID_secp384r1);
[dir: ./crypto/ec/ec_key.c]
EC_KEY *EC_KEY_new_by_curve_name(int nid)
{
EC_KEY *ret = EC_KEY_new();
if (ret == NULL)
return NULL;
ret->group = EC_GROUP_new_by_curve_name(nid);
if (ret->group == NULL) {
EC_KEY_free(ret);
return NULL;
}
if (ret->meth->set_group != NULL
&& ret->meth->set_group(ret, ret->group) == 0) {
EC_KEY_free(ret);
return NULL;
}
return ret;
}
which calls ``EC_GROUP_new_by_curve_name(int nid) ``` [ dir: openssl/crypto/ec/ec_curve.c]
EC_GROUP *EC_GROUP_new_by_curve_name(int nid)
{
size_t i;
EC_GROUP *ret = NULL;
if (nid <= 0)
return NULL;
for (i = 0; i < curve_list_length; i++)
if (curve_list[i].nid == nid) {
ret = ec_group_new_from_data(curve_list[i]);
break;
}
if (ret == NULL) {
ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP);
return NULL;
}
return ret;
}
typedef struct _ec_list_element_st {
int nid;
const EC_CURVE_DATA *data;
const EC_METHOD *(*meth) (void);
const char *comment;
} ec_list_element;
static const ec_list_element curve_list[] = {
/* prime field curves */
/* secg curves */
{NID_secp112r1, &_EC_SECG_PRIME_112R1.h, 0,
"SECG/WTLS curve over a 112 bit prime field"},
{NID_secp112r2, &_EC_SECG_PRIME_112R2.h, 0,
"SECG curve over a 112 bit prime field"},
{NID_secp128r1, &_EC_SECG_PRIME_128R1.h, 0,
"SECG curve over a 128 bit prime field"},
{NID_secp128r2, &_EC_SECG_PRIME_128R2.h, 0,
"SECG curve over a 128 bit prime field"},
{NID_secp160k1, &_EC_SECG_PRIME_160K1.h, 0,
"SECG curve over a 160 bit prime field"},
{NID_secp160r1, &_EC_SECG_PRIME_160R1.h, 0,
"SECG curve over a 160 bit prime field"},
{NID_secp160r2, &_EC_SECG_PRIME_160R2.h, 0,
"SECG/WTLS curve over a 160 bit prime field"},
/* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */
{NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0,
"SECG curve over a 192 bit prime field"},
{NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0,
"SECG curve over a 224 bit prime field"},
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
{NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method,
"NIST/SECG curve over a 224 bit prime field"},
#else
{NID_secp224r1, &_EC_NIST_PRIME_224.h, 0,
"NIST/SECG curve over a 224 bit prime field"},
#endif
{NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0,
"SECG curve over a 256 bit prime field"},
/* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
{NID_secp384r1, &_EC_NIST_PRIME_384.h, 0,
"NIST/SECG curve over a 384 bit prime field"},
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
{NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method,
"NIST/SECG curve over a 521 bit prime field"},
#else
{NID_secp521r1, &_EC_NIST_PRIME_521.h, 0,
"NIST/SECG curve over a 521 bit prime field"},
#endif
/* X9.62 curves */
{NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0,
"NIST/X9.62/SECG curve over a 192 bit prime field"},
{NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, 0,
"X9.62 curve over a 192 bit prime field"},
{NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, 0,
"X9.62 curve over a 192 bit prime field"},
{NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0,
"X9.62 curve over a 239 bit prime field"},
{NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0,
"X9.62 curve over a 239 bit prime field"},
{NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0,
"X9.62 curve over a 239 bit prime field"},
{NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h,
#if defined(ECP_NISTZ256_ASM)
EC_GFp_nistz256_method,
#elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
EC_GFp_nistp256_method,
#else
0,
#endif
"X9.62/SECG curve over a 256 bit prime field"},
#ifndef OPENSSL_NO_EC2M
/* characteristic two field curves */
/* NIST/SECG curves */
{NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0,
"SECG curve over a 113 bit binary field"},
{NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, 0,
"SECG curve over a 113 bit binary field"},
{NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, 0,
"SECG/WTLS curve over a 131 bit binary field"},
{NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, 0,
"SECG curve over a 131 bit binary field"},
{NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0,
"NIST/SECG/WTLS curve over a 163 bit binary field"},
{NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, 0,
"SECG curve over a 163 bit binary field"},
{NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0,
"NIST/SECG curve over a 163 bit binary field"},
{NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, 0,
"SECG curve over a 193 bit binary field"},
{NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, 0,
"SECG curve over a 193 bit binary field"},
{NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0,
"NIST/SECG/WTLS curve over a 233 bit binary field"},
{NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0,
"NIST/SECG/WTLS curve over a 233 bit binary field"},
{NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, 0,
"SECG curve over a 239 bit binary field"},
{NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0,
"NIST/SECG curve over a 283 bit binary field"},
{NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0,
"NIST/SECG curve over a 283 bit binary field"},
{NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0,
"NIST/SECG curve over a 409 bit binary field"},
{NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0,
"NIST/SECG curve over a 409 bit binary field"},
{NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0,
"NIST/SECG curve over a 571 bit binary field"},
{NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0,
"NIST/SECG curve over a 571 bit binary field"},
/* X9.62 curves */
{NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, 0,
"X9.62 curve over a 163 bit binary field"},
{NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, 0,
"X9.62 curve over a 163 bit binary field"},
{NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, 0,
"X9.62 curve over a 163 bit binary field"},
{NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, 0,
"X9.62 curve over a 176 bit binary field"},
{NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, 0,
"X9.62 curve over a 191 bit binary field"},
{NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, 0,
"X9.62 curve over a 191 bit binary field"},
{NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, 0,
"X9.62 curve over a 191 bit binary field"},
{NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, 0,
"X9.62 curve over a 208 bit binary field"},
{NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, 0,
"X9.62 curve over a 239 bit binary field"},
{NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, 0,
"X9.62 curve over a 239 bit binary field"},
{NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, 0,
"X9.62 curve over a 239 bit binary field"},
{NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, 0,
"X9.62 curve over a 272 bit binary field"},
{NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, 0,
"X9.62 curve over a 304 bit binary field"},
{NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, 0,
"X9.62 curve over a 359 bit binary field"},
{NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, 0,
"X9.62 curve over a 368 bit binary field"},
{NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, 0,
"X9.62 curve over a 431 bit binary field"},
/*
* the WAP/WTLS curves [unlike SECG, spec has its own OIDs for curves
* from X9.62]
*/
{NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, 0,
"WTLS curve over a 113 bit binary field"},
{NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, 0,
"NIST/SECG/WTLS curve over a 163 bit binary field"},
{NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, 0,
"SECG curve over a 113 bit binary field"},
{NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0,
"X9.62 curve over a 163 bit binary field"},
#endif
{NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0,
"SECG/WTLS curve over a 112 bit prime field"},
{NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0,
"SECG/WTLS curve over a 160 bit prime field"},
{NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, 0,
"WTLS curve over a 112 bit prime field"},
{NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0,
"WTLS curve over a 160 bit prime field"},
#ifndef OPENSSL_NO_EC2M
{NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0,
"NIST/SECG/WTLS curve over a 233 bit binary field"},
{NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0,
"NIST/SECG/WTLS curve over a 233 bit binary field"},
#endif
{NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0,
"WTLS curve over a 224 bit prime field"},
#ifndef OPENSSL_NO_EC2M
/* IPSec curves */
{NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0,
"\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n"
"\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
{NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0,
"\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n"
"\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
#endif
/* brainpool curves */
{NID_brainpoolP160r1, &_EC_brainpoolP160r1.h, 0,
"RFC 5639 curve over a 160 bit prime field"},
{NID_brainpoolP160t1, &_EC_brainpoolP160t1.h, 0,
"RFC 5639 curve over a 160 bit prime field"},
{NID_brainpoolP192r1, &_EC_brainpoolP192r1.h, 0,
"RFC 5639 curve over a 192 bit prime field"},
{NID_brainpoolP192t1, &_EC_brainpoolP192t1.h, 0,
"RFC 5639 curve over a 192 bit prime field"},
{NID_brainpoolP224r1, &_EC_brainpoolP224r1.h, 0,
"RFC 5639 curve over a 224 bit prime field"},
{NID_brainpoolP224t1, &_EC_brainpoolP224t1.h, 0,
"RFC 5639 curve over a 224 bit prime field"},
{NID_brainpoolP256r1, &_EC_brainpoolP256r1.h, 0,
"RFC 5639 curve over a 256 bit prime field"},
{NID_brainpoolP256t1, &_EC_brainpoolP256t1.h, 0,
"RFC 5639 curve over a 256 bit prime field"},
{NID_brainpoolP320r1, &_EC_brainpoolP320r1.h, 0,
"RFC 5639 curve over a 320 bit prime field"},
{NID_brainpoolP320t1, &_EC_brainpoolP320t1.h, 0,
"RFC 5639 curve over a 320 bit prime field"},
{NID_brainpoolP384r1, &_EC_brainpoolP384r1.h, 0,
"RFC 5639 curve over a 384 bit prime field"},
{NID_brainpoolP384t1, &_EC_brainpoolP384t1.h, 0,
"RFC 5639 curve over a 384 bit prime field"},
{NID_brainpoolP512r1, &_EC_brainpoolP512r1.h, 0,
"RFC 5639 curve over a 512 bit prime field"},
{NID_brainpoolP512t1, &_EC_brainpoolP512t1.h, 0,
"RFC 5639 curve over a 512 bit prime field"},
#ifndef OPENSSL_NO_SM2
{NID_sm2, &_EC_sm2p256v1.h, 0,
"SM2 curve over a 256 bit prime field"},
#endif
};
It is unclear to me how to extend this table for the OQS algorithms: what the values would be and if there is any extra logic that needs to be added anywhere else to make this work like a charm.
Now the openvpn curve list makes sense, it is exactly the list above.
openvpn --show-curves
Available Elliptic curves:
secp112r1
secp112r2
secp128r1
secp128r2
secp160k1
secp160r1
secp160r2
secp192k1
secp224k1
secp224r1
secp256k1
secp384r1
secp521r1
prime192v1
prime192v2
prime192v3
prime239v1
prime239v2
prime239v3
prime256v1
sect113r1
sect113r2
sect131r1
sect131r2
sect163k1
sect163r1
sect163r2
sect193r1
sect193r2
sect233k1
sect233r1
sect239k1
sect283k1
sect283r1
sect409k1
sect409r1
sect571k1
sect571r1
c2pnb163v1
c2pnb163v2
c2pnb163v3
c2pnb176v1
c2tnb191v1
c2tnb191v2
c2tnb191v3
c2pnb208w1
c2tnb239v1
c2tnb239v2
c2tnb239v3
c2pnb272w1
c2pnb304w1
c2tnb359v1
c2pnb368w1
c2tnb431r1
wap-wsg-idm-ecid-wtls1
wap-wsg-idm-ecid-wtls3
wap-wsg-idm-ecid-wtls4
wap-wsg-idm-ecid-wtls5
wap-wsg-idm-ecid-wtls6
wap-wsg-idm-ecid-wtls7
wap-wsg-idm-ecid-wtls8
wap-wsg-idm-ecid-wtls9
wap-wsg-idm-ecid-wtls10
wap-wsg-idm-ecid-wtls11
wap-wsg-idm-ecid-wtls12
Oakley-EC2N-3
Oakley-EC2N-4
brainpoolP160r1
brainpoolP160t1
brainpoolP192r1
brainpoolP192t1
brainpoolP224r1
brainpoolP224t1
brainpoolP256r1
brainpoolP256t1
brainpoolP320r1
brainpoolP320t1
brainpoolP384r1
brainpoolP384t1
brainpoolP512r1
brainpoolP512t1
SM2
For the OpenSSl s_server/s_client in the 1.0.2 archived fork using TLSv1.2 I was able to verify that kyber1024 works because I can see that "random bytes" used in the exchange are the exact size it should be for that parameter per the NIST submission paper for kyber, and also because the ciphersuite for that algorithm is chosen by the server when it's the only one the client lists as available -- I wanted to make sure it chose that one.
But, nginx on TLSv1.3 under OQS-OpenSSL-1.1.1-stable is a different beast. For one thing, I am never able to see the TLS handshake in traffic, never happens...it is a mystery to me what is going on there, or if my chosen cipher suite in the nginx conf file is ever chosen. Also, the output of the openssl s_client is not exactly showing if the KEM/KEX chosen is actually used. The only thing that is clear is that the certificates are being validated; I can't say anything beyond that.
Could you please confirm or let me know I did something wrong.
Update: The reason I was not able to see the nginx traffic is silly...it turns out you have to enable docker containers to have access to your network, else all traffic is internal to docker. So open ports to the outside world with -p hostport:containerport
or the whole thing with --network host
. After that I was able to see the nginx traffic and it looks fine.
May I suggest you try out OQS-nginx: When running that, openssl s_client
always shows the temp k[ex] (type) chosen, e.g.:
No client certificate CA names sent
Peer signature type: Dilithium-2
Server Temp Key: saber
---
SSL handshake has read 6961 bytes and written 1383 bytes
Verification: OK
(generated by executing the example code): Use any of the KEMs supported and you will see Server Temp Key
(type) changing, as well as data lengths and timings change (roughly in line with what is expected for each algorithm). You can even trigger classic EC, e.g., by passing (KEX=)X448
as the curves
parameter.
@baentsch Ah, yes I see that. However, I still cannot see the TLS hello in the traffic, can you see the raw packets with that key negotiated?
@ReverseControl Yes. openssl s_client -debug
.
@baentsch I still cannot see the TLS handshake in traffic; that is to say, capturing traffic independent of openssl for verification.
Using the debug flag I noticed the following:
/opt/openssl/apps/openssl s_client -curves kyber1024 -debug -connect localhost:4433
...
...
...
---
No client certificate CA names sent
Peer signature type: Dilithium-2
Server Temp Key: kyber1024
---
SSL handshake has read 7297 bytes and written 1941 bytes
Verification error: unable to verify the first certificate
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 9472 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 21 (unable to verify the first certificate)
---
...
...
...
Is this public key meant to be the kyber2014 public key? Because the size of that key, per the NIST submission paper, is exactly 1568 bytes which is not 9472 bits.
Is this public key meant to be the kyber2014 public key? Because the size of that key, per the NIST submission paper, is exactly 1568 bytes which is not 9472 bits.
Public key here refers to the signature scheme (which in this case is Dilithium 2) not the KEM for the key exchange.
I tested with OpenVPN, it does not work. No Quantum KEMs/KEXs "curves" are recognized. The server uses the below curves as expected, I tested, but with "kyber512" and "frodo640aes" as per your example I get
OpenVPN doesn't work with our fork TLS 1.3 OpenSSL 1.1.1 fork. Even if you had the code to find the curve, you still get errors because OpenSSL is trying to parse the alg as an actual elliptic curve. More modifications would be needed on OpenVPN to make this work.
The TLS1.3 OpenSSL 1.1.1 fork works just fine with nginx; i looked at the source code and it does not seem to do anything that much different than the OpenVPN source code to handle TLS, other than being much better organized and readable.
What needs to be done to make OpenVPN work with the TLS1.3 OpenSSL 1.1.1 fork? I can give it a shot to integrate it, after all nginx already uses it and it works like a charm.
What needs to be done to make OpenVPN work with the TLS1.3 OpenSSL 1.1.1 fork?
This is on the list of things to investigate...
Update: The reason I was not able to see the nginx traffic is silly...it turns out you have to enable docker containers to have access to your network, else all traffic is internal to docker. So open ports to the outside world with -p hostport:containerport
or the whole thing with --network host
. After that I was able to see the nginx traffic and it looks fine for nginx.
@christianpaquin why can't we have nice things that just work? :(
It is unclear, and seemingly impossible after trying hard, to select a quantum algorithm for KEM/KEX of my choice, or at all for that matter. The example given with the internal TLS server/client designed for testing works like a charm, but if I wanted to choose a quantum algorithm for KEM/KEX say for a vpn, or generate the parameters to use one for a configuration file, there seems to be no way of doing this. With the OQS-Openssl_1.0.2 one can specify the ciphersuite and that takes care of it because in that version the ciphersuite definition includes the KEM/KEX, but in OpenSSL 1.1.1 KEM/KEX is no longer in the ciphersuite, and creating "curves" for the Qalgorithms using the OpenSSL API for EC is no go.
Even the demos for nginx/curl/httpd do not mention how to choose one over the others. Could you please advice on how to do this?
Thank you.