The NIST round 3 Falcon Signature Scheme integration.

pull/4530/head
Anthony Hu 2021-10-14 10:43:08 -04:00
parent 2745f394e5
commit 81def76b18
14 changed files with 2105 additions and 156 deletions

72
INSTALL
View File

@ -137,11 +137,16 @@
Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat
3) Follow steps in "Unix-based Platforms" above.
15. Building with liboqs for TLS 1.3 KEM Groups [EXPERIMENTAL]
15. Building with liboqs for TLS 1.3 [EXPERIMENTAL]
In order be able to use liboqs, you must have it built and installed on your
system. For example, on linux, this would be sufficient:
system. We support the 0.7.0 release of liboqs. You can get it by looking at
the "Assets" section of the following page:
$ cd liboqs
https://github.com/open-quantum-safe/liboqs/releases/tag/0.7.0
Once unpacked, this would be sufficient:
$ cd liboqs-0.7.0
$ mkdir build
$ cd build
$ cmake -DOQS_USE_OPENSSL=0 ..
@ -155,8 +160,8 @@
$ ./configure --with-liboqs
$ make all
Execute the following to see the liboqs-related options near the end of the
output of these commands:
Execute the following to see the liboqs-related options for KEM groups near
the end of the output of these commands:
$ ./examples/server/server -?
$ ./examples/client/client -?
@ -172,14 +177,59 @@
Using OQS KEM: P521_KYBER_LEVEL5
```
The following NIST Competition Round 3 Finalist KEMs are supported:
- CRYSTALS-KYBER
- SABER
- NTRU
For authentication, you can generate a certificate chain using the Open
Quantum Safe project's fork of OpenSSL. We support certificates and keys
generated by the 2021-08 snapshot of the OQS-OpenSSL_1_1_1-stable branch
of the fork. You can get it by looking at the "Assets" section of the
following page:
https://github.com/open-quantum-safe/openssl/releases/tag/OQS-OpenSSL_1_1_1-stable-snapshot-2021-08
Once unpacked, this would be sufficient for building it:
$ cd openssl-OQS-OpenSSL_1_1_1-stable-snapshot-2021-08/
$ ./config no-shared
$ make all
Note that installation is NOT required.
There is a script for generating a Falcon NIST Level 1 and NIST Level 5
certificate chain which can be found in the wolfssl-examples github repo at
certmanager/generate_falcon_chains.sh. Please find detailed instructions on
how to generate and verify the keys and certificates in
certmanager/README.md.
Once the certificates and keys are generated, copy them from the
openssl-OQS-OpenSSL_1_1_1-stable-snapshot-2021-08/ directory to the certs
directory of wolfssl. Now you can run the server and client like this:
$ examples/server/server -v 4 -l TLS_AES_256_GCM_SHA384 \
-A certs/falcon_level5_root_cert.pem \
-c certs/falcon_level1_entity_cert.pem \
-k certs/falcon_level1_entity_key.pem \
--oqs P521_KYBER_LEVEL5
$ examples/client/client -v 4 -l TLS_AES_256_GCM_SHA384 \
-A certs/falcon_level1_root_cert.pem \
-c certs/falcon_level5_entity_cert.pem \
-k certs/falcon_level5_entity_key.pem \
--oqs P521_KYBER_LEVEL5
Congratulations! You have just achieved a fully quantum-safe TLS 1.3
connection!
The following NIST Competition Round 3 Finalist algorithms are supported:
- CRYSTALS-KYBER (KEM)
- SABER (KEM)
- NTRU (KEM)
- FALCON (signature scheme)
Links to more information about these algorithms can be found here:
https://csrc.nist.gov/projects/post-quantum-cryptography/round-3-submissions
NOTE: The quantum-safe algorithms provided by LIBOQS are unstandardized and
NOTE: The quantum-safe algorithms provided by liboqs are unstandardized and
experimental. It is highly advised that they NOT be used in production
environments.
environments. All OIDs and codepoints are temporary and expected to
change in the future. You should have no expectation of backwards
compatibility.

View File

@ -688,6 +688,10 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/fe_448.c
endif
endif
if BUILD_LIBOQS
src_libwolfssl_la_SOURCES += wolfcrypt/src/falcon.c
endif
if BUILD_LIBZ
src_libwolfssl_la_SOURCES += wolfcrypt/src/compress.c
endif

View File

@ -2000,6 +2000,11 @@ int InitSSL_Side(WOLFSSL* ssl, word16 side)
ssl->options.haveECC = 1; /* server turns on with ECC key cert */
}
#endif
#ifdef HAVE_LIBOQS
if (ssl->options.side == WOLFSSL_CLIENT_END) {
ssl->options.haveFalconSig = 1; /* always on client side */
}
#endif
#if defined(HAVE_EXTENDED_MASTER) && !defined(NO_WOLFSSL_CLIENT)
if (ssl->options.side == WOLFSSL_CLIENT_END) {
@ -2062,6 +2067,9 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap)
#ifdef HAVE_ECC
ctx->minEccKeySz = MIN_ECCKEY_SZ;
ctx->eccTempKeySz = ECDHE_SIZE;
#endif
#ifdef HAVE_LIBOQS
ctx->minFalconKeySz = MIN_FALCONKEY_SZ;
#endif
ctx->verifyDepth = MAX_CHAIN_DEPTH;
#ifdef OPENSSL_EXTRA
@ -2117,6 +2125,11 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap)
ctx->CBIOSend = GNRC_SendTo;
#endif
#ifdef HAVE_LIBOQS
if (method->side == WOLFSSL_CLIENT_END)
ctx->haveFalconSig = 1; /* always on client side */
/* server can turn on by loading key */
#endif
#ifdef HAVE_ECC
if (method->side == WOLFSSL_CLIENT_END) {
ctx->haveECDSAsig = 1; /* always on client side */
@ -2649,6 +2662,22 @@ static WC_INLINE void AddSuiteHashSigAlgo(Suites* suites, byte macAlgo,
}
else
#endif
#ifdef HAVE_LIBOQS
if (sigAlgo == falcon_level1_sa_algo) {
suites->hashSigAlgo[*inOutIdx] = FALCON_LEVEL1_SA_MAJOR;
*inOutIdx += 1;
suites->hashSigAlgo[*inOutIdx] = FALCON_LEVEL1_SA_MINOR;
*inOutIdx += 1;
}
else
if (sigAlgo == falcon_level5_sa_algo) {
suites->hashSigAlgo[*inOutIdx] = FALCON_LEVEL5_SA_MAJOR;
*inOutIdx += 1;
suites->hashSigAlgo[*inOutIdx] = FALCON_LEVEL5_SA_MINOR;
*inOutIdx += 1;
}
else
#endif
#ifdef WC_RSA_PSS
if (sigAlgo == rsa_pss_sa_algo) {
/* RSA PSS is sig then mac */
@ -2676,7 +2705,8 @@ static WC_INLINE void AddSuiteHashSigAlgo(Suites* suites, byte macAlgo,
}
void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, int haveRSAsig,
int haveAnon, int tls1_2, int keySz)
int haveFalconSig, int haveAnon, int tls1_2,
int keySz)
{
word16 idx = 0;
@ -2707,8 +2737,13 @@ void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, int haveRSAsig,
AddSuiteHashSigAlgo(suites, no_mac, ed448_sa_algo, keySz, &idx);
#endif
}
#endif /* HAVE_ECC || HAVE_ED25519 || defined(HAVE_ED448 */
#endif /* HAVE_ECC || HAVE_ED25519 || HAVE_ED448 */
if (haveFalconSig) {
#if defined(HAVE_LIBOQS)
AddSuiteHashSigAlgo(suites, no_mac, falcon_level1_sa_algo, keySz, &idx);
AddSuiteHashSigAlgo(suites, no_mac, falcon_level5_sa_algo, keySz, &idx);
#endif /* HAVE_LIBOQS */
}
if (haveRSAsig) {
#ifdef WC_RSA_PSS
if (tls1_2) {
@ -2757,8 +2792,8 @@ void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, int haveRSAsig,
void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA,
word16 havePSK, word16 haveDH, word16 haveECDSAsig,
word16 haveECC, word16 haveStaticECC, word16 haveAnon,
int side)
word16 haveECC, word16 haveStaticECC, word16 haveFalconSig,
word16 haveAnon, int side)
{
word16 idx = 0;
int tls = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_MINOR;
@ -2780,6 +2815,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA,
(void)haveRSA; /* some builds won't read */
(void)haveRSAsig; /* non ecc builds won't read */
(void)haveAnon; /* anon ciphers optional */
(void)haveFalconSig;
if (suites == NULL) {
WOLFSSL_MSG("InitSuites pointer error");
@ -3723,7 +3759,8 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA,
if (suites->hashSigAlgoSz == 0) {
InitSuitesHashSigAlgo(suites, haveECDSAsig | haveECC,
haveRSAsig | haveRSA, 0, tls1_2, keySz);
haveRSAsig | haveRSA, haveFalconSig,
0, tls1_2, keySz);
}
}
@ -3771,6 +3808,20 @@ static WC_INLINE void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsTy
*hashAlgo = input[1];
}
break;
#ifdef HAVE_LIBOQS
case OQS_SA_MAJOR:
if (input[1] == FALCON_LEVEL1_SA_MINOR) {
*hsType = falcon_level1_sa_algo;
/* Hash performed as part of sign/verify operation. */
*hashAlgo = sha512_mac;
} else
if (input[1] == FALCON_LEVEL5_SA_MINOR) {
*hsType = falcon_level5_sa_algo;
/* Hash performed as part of sign/verify operation. */
*hashAlgo = sha512_mac;
}
break;
#endif
default:
*hashAlgo = input[0];
*hsType = input[1];
@ -5680,13 +5731,14 @@ int InitSSL_Suites(WOLFSSL* ssl)
InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
ssl->options.haveDH, ssl->options.haveECDSAsig,
ssl->options.haveECC, ssl->options.haveStaticECC,
ssl->options.haveAnon, ssl->options.side);
ssl->options.haveFalconSig, ssl->options.haveAnon,
ssl->options.side);
}
else {
InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK, TRUE,
ssl->options.haveECDSAsig, ssl->options.haveECC,
ssl->options.haveStaticECC, ssl->options.haveAnon,
ssl->options.side);
ssl->options.haveStaticECC, ssl->options.haveFalconSig,
ssl->options.haveAnon, ssl->options.side);
}
#if !defined(NO_CERTS) && !defined(WOLFSSL_SESSION_EXPORT)
@ -5872,6 +5924,7 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
ssl->options.haveECDSAsig = ctx->haveECDSAsig;
ssl->options.haveECC = ctx->haveECC;
ssl->options.haveStaticECC = ctx->haveStaticECC;
ssl->options.haveFalconSig = ctx->haveFalconSig;
#ifndef NO_PSK
ssl->options.havePSK = ctx->havePSK;
@ -5902,6 +5955,9 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
#ifdef HAVE_ECC
ssl->options.minEccKeySz = ctx->minEccKeySz;
#endif
#ifdef HAVE_LIBOQS
ssl->options.minFalconKeySz = ctx->minFalconKeySz;
#endif
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
ssl->options.verifyDepth = ctx->verifyDepth;
#endif
@ -6644,6 +6700,11 @@ void FreeKey(WOLFSSL* ssl, int type, void** pKey)
wc_curve448_free((curve448_key*)*pKey);
break;
#endif /* HAVE_CURVE448 */
#ifdef HAVE_LIBOQS
case DYNAMIC_TYPE_FALCON:
wc_falcon_free((falcon_key*)*pKey);
break;
#endif /* HAVE_LIBOQS */
#ifndef NO_DH
case DYNAMIC_TYPE_DH:
wc_FreeDhKey((DhKey*)*pKey);
@ -6706,6 +6767,11 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey)
sz = sizeof(curve448_key);
break;
#endif /* HAVE_CURVE448 */
#ifdef HAVE_LIBOQS
case DYNAMIC_TYPE_FALCON:
sz = sizeof(falcon_key);
break;
#endif /* HAVE_LIBOQS */
#ifndef NO_DH
case DYNAMIC_TYPE_DH:
sz = sizeof(DhKey);
@ -6751,6 +6817,12 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey)
ret = 0;
break;
#endif /* HAVE_CURVE448 */
#ifdef HAVE_LIBOQS
case DYNAMIC_TYPE_FALCON:
wc_falcon_init((falcon_key*)*pKey);
ret = 0;
break;
#endif
#ifdef HAVE_CURVE448
case DYNAMIC_TYPE_CURVE448:
wc_curve448_init((curve448_key*)*pKey);
@ -6775,7 +6847,8 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey)
}
#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
defined(HAVE_CURVE25519) || defined(HAVE_ED448) || defined(HAVE_CURVE448)
defined(HAVE_CURVE25519) || defined(HAVE_ED448) || \
defined(HAVE_CURVE448) || defined(HAVE_LIBOQS)
static int ReuseKey(WOLFSSL* ssl, int type, void* pKey)
{
int ret = 0;
@ -6821,6 +6894,12 @@ static int ReuseKey(WOLFSSL* ssl, int type, void* pKey)
ret = wc_curve448_init((curve448_key*)pKey);
break;
#endif /* HAVE_CURVE448 */
#ifdef HAVE_LIBOQS
case DYNAMIC_TYPE_FALCON:
wc_falcon_free((falcon_key*)pKey);
ret = wc_falcon_init((falcon_key*)pKey);
break;
#endif /* HAVE_LIBOQS */
#ifndef NO_DH
case DYNAMIC_TYPE_DH:
wc_FreeDhKey((DhKey*)pKey);
@ -7056,6 +7135,10 @@ void SSL_ResourceFree(WOLFSSL* ssl)
}
#endif
#endif
#ifdef HAVE_LIBOQS
FreeKey(ssl, DYNAMIC_TYPE_FALCON, (void**)&ssl->peerFalconKey);
ssl->peerFalconKeyPresent = 0;
#endif
#ifdef HAVE_PK_CALLBACKS
#ifdef HAVE_ECC
XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
@ -7273,6 +7356,10 @@ void FreeHandshakeResources(WOLFSSL* ssl)
FreeKey(ssl, DYNAMIC_TYPE_ED448, (void**)&ssl->peerEd448Key);
ssl->peerEd448KeyPresent = 0;
#endif /* HAVE_ED448 */
#ifdef HAVE_LIBOQS
FreeKey(ssl, DYNAMIC_TYPE_FALCON, (void**)&ssl->peerFalconKey);
ssl->peerFalconKeyPresent = 0;
#endif /* HAVE_LIBOQS */
}
#ifdef HAVE_ECC
@ -11719,6 +11806,24 @@ static int ProcessPeerCertCheckKey(WOLFSSL* ssl, ProcPeerCertArgs* args)
}
break;
#endif /* HAVE_ED448 */
#ifdef HAVE_LIBOQS
case FALCON_LEVEL1k:
if (ssl->options.minFalconKeySz < 0 ||
FALCON_LEVEL1_KEY_SIZE < (word16)ssl->options.minFalconKeySz) {
WOLFSSL_MSG(
"Falcon key size in cert chain error");
ret = FALCON_KEY_SIZE_E;
}
break;
case FALCON_LEVEL5k:
if (ssl->options.minFalconKeySz < 0 ||
FALCON_LEVEL5_KEY_SIZE < (word16)ssl->options.minFalconKeySz) {
WOLFSSL_MSG(
"Falcon key size in cert chain error");
ret = FALCON_KEY_SIZE_E;
}
break;
#endif /* HAVE_LIBOQS */
default:
WOLFSSL_MSG("Key size not checked");
/* key not being checked for size if not in
@ -12898,6 +13003,52 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
break;
}
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
#ifdef HAVE_LIBOQS
case FALCON_LEVEL1k:
case FALCON_LEVEL5k:
{
int keyRet = 0;
if (ssl->peerFalconKey == NULL) {
/* alloc/init on demand */
keyRet = AllocKey(ssl, DYNAMIC_TYPE_FALCON,
(void**)&ssl->peerFalconKey);
} else if (ssl->peerFalconKeyPresent) {
keyRet = ReuseKey(ssl, DYNAMIC_TYPE_FALCON,
ssl->peerFalconKey);
ssl->peerFalconKeyPresent = 0;
}
if (keyRet == 0) {
if (args->dCert->keyOID == FALCON_LEVEL1k) {
keyRet = wc_falcon_set_level(ssl->peerFalconKey,
1);
}
else {
keyRet = wc_falcon_set_level(ssl->peerFalconKey,
5);
}
}
if (keyRet != 0 ||
wc_falcon_import_public(args->dCert->publicKey,
args->dCert->pubKeySize,
ssl->peerFalconKey) != 0) {
ret = PEER_KEY_ERROR;
}
else {
ssl->peerFalconKeyPresent = 1;
}
/* check size of peer Falcon key */
if (ret == 0 && ssl->peerFalconKeyPresent &&
!ssl->options.verifyNone &&
FALCON_MAX_KEY_SIZE <
ssl->options.minFalconKeySz) {
ret = FALCON_KEY_SIZE_E;
WOLFSSL_MSG("Peer Falcon key is too small");
}
}
#endif /* HAVE_LIBOQS */
default:
break;
}
@ -20364,6 +20515,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
return "bad/unsupported protocol version";
#endif
case FALCON_KEY_SIZE_E:
return "Wrong key size for Falcon.";
default :
return "unknown error number";
}
@ -21316,13 +21470,14 @@ Set the enabled cipher suites.
*/
int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list)
{
int ret = 0;
int idx = 0;
int haveRSAsig = 0;
int haveECDSAsig = 0;
int haveAnon = 0;
const int suiteSz = GetCipherNamesSize();
char* next = (char*)list;
int ret = 0;
int idx = 0;
int haveRSAsig = 0;
int haveECDSAsig = 0;
int haveFalconSig = 0;
int haveAnon = 0;
const int suiteSz = GetCipherNamesSize();
char* next = (char*)list;
if (suites == NULL || list == NULL) {
WOLFSSL_MSG("SetCipherList parameter error");
@ -21392,6 +21547,9 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list)
defined(HAVE_ED448)
haveECDSAsig = 1;
#endif
#if defined(HAVE_LIBOQS)
haveFalconSig = 1;
#endif
}
else
#endif
@ -21428,8 +21586,8 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list)
#endif
suites->setSuites = 1;
suites->suiteSz = (word16)idx;
InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, haveAnon, 1,
keySz);
InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, haveFalconSig,
haveAnon, 1, keySz);
}
(void)ctx;
@ -21608,6 +21766,18 @@ static int MatchSigAlgo(WOLFSSL* ssl, int sigAlgo)
return sigAlgo == ed448_sa_algo;
}
#endif
#ifdef HAVE_LIBOQS
if (ssl->pkCurveOID == CTC_FALCON_LEVEL1) {
/* Certificate has Falcon level 1 key, only match with Falcon level 1
* sig alg */
return sigAlgo == falcon_level1_sa_algo;
}
if (ssl->pkCurveOID == CTC_FALCON_LEVEL5) {
/* Certificate has Falcon level 5 key, only match with Falcon level 5
* sig alg */
return sigAlgo == falcon_level5_sa_algo;
}
#endif
#ifdef WC_RSA_PSS
/* RSA certificate and PSS sig alg. */
if (ssl->suites->sigAlgo == rsa_sa_algo) {
@ -21710,6 +21880,16 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz)
break;
}
#endif
#if defined(HAVE_LIBOQS)
if (ssl->pkCurveOID == CTC_FALCON_LEVEL1 ||
ssl->pkCurveOID == CTC_FALCON_LEVEL5 ) {
/* Matched Falcon - set chosen and finished. */
ssl->suites->sigAlgo = sigAlgo;
ssl->suites->hashAlgo = hashAlgo;
ret = 0;
break;
}
#endif
#if defined(WOLFSSL_ECDSA_MATCH_HASH) && defined(USE_ECDSA_KEYSZ_HASH_ALGO)
#error "WOLFSSL_ECDSA_MATCH_HASH and USE_ECDSA_KEYSZ_HASH_ALGO cannot "
@ -22074,7 +22254,9 @@ int CreateDevPrivateKey(void** pkey, byte* data, word32 length, int hsType,
}
#endif
/* Decode the private key - RSA/ECC/Ed25519/Ed448 - and creates a key object.
/* Decode the private key - RSA/ECC/Ed25519/Ed448/Falcon - and creates a key
* object.
*
* The signature type is set as well.
* The maximum length of a signature is returned.
*
@ -22364,6 +22546,67 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
}
}
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
#ifdef HAVE_LIBOQS
if (ssl->buffers.keyType == falcon_level1_sa_algo ||
ssl->buffers.keyType == falcon_level5_sa_algo ||
ssl->buffers.keyType == 0) {
ssl->hsType = DYNAMIC_TYPE_FALCON;
ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
if (ret != 0) {
goto exit_dpk;
}
if (ssl->buffers.keyType == falcon_level1_sa_algo) {
ret = wc_falcon_set_level((falcon_key*)ssl->hsKey, 1);
}
else if (ssl->buffers.keyType == falcon_level5_sa_algo) {
ret = wc_falcon_set_level((falcon_key*)ssl->hsKey, 5);
}
else {
/* What if ssl->buffers.keyType is 0? We might want to do something
* more graceful here. */
ret = ALGO_ID_E;
}
if (ret != 0) {
goto exit_dpk;
}
#if defined(HAVE_ED448)
WOLFSSL_MSG("Trying Falcon private key, ED448 didn't work");
#elif defined(HAVE_ED25519)
WOLFSSL_MSG("Trying Falcon private key, ED25519 didn't work");
#elif defined(HAVE_ECC)
WOLFSSL_MSG("Trying Falcon private key, ECC didn't work");
#elif !defined(NO_RSA)
WOLFSSL_MSG("Trying Falcon private key, RSA didn't work");
#else
WOLFSSL_MSG("Trying Falcon private key");
#endif
/* Set start of data to beginning of buffer. */
idx = 0;
/* Decode the key assuming it is a Falcon private key. */
ret = wc_falcon_import_private_only(ssl->buffers.key->buffer,
ssl->buffers.key->length,
(falcon_key*)ssl->hsKey);
if (ret == 0) {
WOLFSSL_MSG("Using Falcon private key");
/* Check it meets the minimum Falcon key size requirements. */
if (FALCON_MAX_KEY_SIZE < ssl->options.minFalconKeySz) {
WOLFSSL_MSG("Falcon key size too small");
ERROR_OUT(FALCON_KEY_SIZE_E, exit_dpk);
}
/* Return the maximum signature length. */
*length = FALCON_MAX_SIG_SIZE;
goto exit_dpk;
}
}
#endif /* HAVE_LIBOQS */
(void)idx;
(void)keySz;
@ -28766,7 +29009,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
ssl->options.haveDH, ssl->options.haveECDSAsig,
ssl->options.haveECC, ssl->options.haveStaticECC,
ssl->options.haveAnon, ssl->options.side);
ssl->options.haveFalconSig, ssl->options.haveAnon,
ssl->options.side);
}
/* suite size */
@ -29119,7 +29363,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
ssl->options.haveDH, ssl->options.haveECDSAsig,
ssl->options.haveECC, ssl->options.haveStaticECC,
ssl->options.haveAnon, ssl->options.side);
ssl->options.haveFalconSig, ssl->options.haveAnon,
ssl->options.side);
}
#ifdef OPENSSL_EXTRA
@ -29179,9 +29424,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* reset cipher suites to account for TLS version change */
InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
ssl->options.haveDH, ssl->options.haveECDSAsig,
ssl->options.haveECC, ssl->options.haveStaticECC,
ssl->options.haveAnon, ssl->options.side);
ssl->options.haveDH, ssl->options.haveECDSAsig,
ssl->options.haveECC, ssl->options.haveStaticECC,
ssl->options.haveFalconSig, ssl->options.haveAnon,
ssl->options.side);
}
}
#endif

182
src/ssl.c
View File

@ -115,6 +115,9 @@
#include <wolfssl/wolfcrypt/curve25519.h>
#include <wolfssl/wolfcrypt/ed25519.h>
#include <wolfssl/wolfcrypt/curve448.h>
#if defined(HAVE_LIBOQS)
#include <wolfssl/wolfcrypt/falcon.h>
#endif
#if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL)
#ifdef HAVE_OCSP
#include <wolfssl/openssl/ocsp.h>
@ -1963,7 +1966,8 @@ int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz,
InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
ssl->options.haveDH, ssl->options.haveECDSAsig,
ssl->options.haveECC, ssl->options.haveStaticECC,
ssl->options.haveAnon, ssl->options.side);
ssl->options.haveFalconSig, ssl->options.haveAnon,
ssl->options.side);
}
WOLFSSL_LEAVE("wolfSSL_SetTmpDH", 0);
@ -3928,6 +3932,10 @@ WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap)
#ifdef HAVE_ECC
cm->minEccKeySz = MIN_ECCKEY_SZ;
#endif
#ifdef HAVE_LIBOQS
cm->minFalconKeySz = MIN_FALCONKEY_SZ;
#endif
cm->heap = heap;
}
@ -4414,7 +4422,8 @@ int wolfSSL_SetVersion(WOLFSSL* ssl, int version)
InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
ssl->options.haveDH, ssl->options.haveECDSAsig,
ssl->options.haveECC, ssl->options.haveStaticECC,
ssl->options.haveAnon, ssl->options.side);
ssl->options.haveFalconSig, ssl->options.haveAnon,
ssl->options.side);
return WOLFSSL_SUCCESS;
}
@ -4871,6 +4880,22 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
}
break;
#endif /* HAVE_ED448 */
#ifdef HAVE_LIBOQS
case FALCON_LEVEL1k:
if (cm->minFalconKeySz < 0 ||
FALCON_LEVEL1_KEY_SIZE < (word16)cm->minFalconKeySz) {
ret = FALCON_KEY_SIZE_E;
WOLFSSL_MSG("\tCA Falcon level 1 key size error");
}
break;
case FALCON_LEVEL5k:
if (cm->minFalconKeySz < 0 ||
FALCON_LEVEL5_KEY_SIZE < (word16)cm->minFalconKeySz) {
ret = FALCON_KEY_SIZE_E;
WOLFSSL_MSG("\tCA Falcon level 5 key size error");
}
break;
#endif /* HAVE_LIBOQS */
default:
WOLFSSL_MSG("\tNo key size check done on CA");
@ -5407,9 +5432,9 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
#endif
if (ret != 0) {
#if !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
!defined(HAVE_ED448)
WOLFSSL_MSG("RSA decode failed and ECC/ED25519/ED448 not "
"enabled to try");
!defined(HAVE_ED448) && !defined(HAVE_LIBOQS)
WOLFSSL_MSG("RSA decode failed and other algorithms "
"not enabled to try");
ret = WOLFSSL_BAD_FILE;
#else
ret = 0; /* continue trying other algorithms */
@ -5600,11 +5625,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
ret = wc_ed448_init(key);
if (ret == 0) {
*idx = 0;
if (wc_Ed448PrivateKeyDecode(der->buffer, idx, key,
der->length) != 0) {
ret = WOLFSSL_BAD_FILE;
}
ret = wc_Ed448PrivateKeyDecode(der->buffer, idx, key, der->length);
if (ret == 0) {
/* check for minimum key size and then free */
int minKeySz = ssl ? ssl->options.minEccKeySz :
@ -5644,6 +5665,71 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
#endif
}
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
#ifdef HAVE_LIBOQS
if (ret == 0 && ((*keyFormat == 0) || (*keyFormat == FALCON_LEVEL1k) ||
(*keyFormat == FALCON_LEVEL5k))) {
/* make sure Falcon key can be used */
falcon_key* key = (falcon_key*)XMALLOC(sizeof(falcon_key), heap,
DYNAMIC_TYPE_FALCON);
if (key == NULL) {
return MEMORY_E;
}
ret = wc_falcon_init(key);
if (ret == 0) {
if (*keyFormat == FALCON_LEVEL1k) {
ret = wc_falcon_set_level(key, 1);
}
else if (*keyFormat == FALCON_LEVEL5k) {
ret = wc_falcon_set_level(key, 5);
}
else {
/* What if *keyformat is 0? We might want to do something more
* graceful here. */
wc_falcon_free(key);
ret = ALGO_ID_E;
}
}
if (ret == 0) {
*idx = 0;
ret = wc_falcon_import_private_only(der->buffer, der->length, key);
if (ret == 0) {
/* check for minimum key size and then free */
int minKeySz = ssl ? ssl->options.minFalconKeySz :
ctx->minFalconKeySz;
*keySz = FALCON_MAX_KEY_SIZE;
if (*keySz < minKeySz) {
WOLFSSL_MSG("Falcon private key too small");
ret = FALCON_KEY_SIZE_E;
}
if (ssl) {
if (*keyFormat == FALCON_LEVEL1k) {
ssl->buffers.keyType = falcon_level1_sa_algo;
}
else {
ssl->buffers.keyType = falcon_level5_sa_algo;
}
ssl->buffers.keySz = *keySz;
}
else if (ctx) {
if (*keyFormat == FALCON_LEVEL1k) {
ctx->privateKeyType = falcon_level1_sa_algo;
}
else {
ctx->privateKeyType = falcon_level5_sa_algo;
}
ctx->privateKeySz = *keySz;
}
if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
*resetSuites = 1;
}
}
wc_falcon_free(key);
}
XFREE(key, heap, DYNAMIC_TYPE_FALCON);
}
#endif /* HAVE_LIBOQS */
return ret;
}
@ -5977,12 +6063,21 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
else if (ctx)
ctx->haveECDSAsig = 1;
break;
case CTC_FALCON_LEVEL1:
case CTC_FALCON_LEVEL5:
WOLFSSL_MSG("Falcon cert signature");
if (ssl)
ssl->options.haveFalconSig = 1;
else if (ctx)
ctx->haveFalconSig = 1;
break;
default:
WOLFSSL_MSG("Not ECDSA cert signature");
break;
}
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
defined(HAVE_LIBOQS)
if (ssl) {
ssl->pkCurveOID = cert->pkCurveOID;
#ifndef WC_STRICT_SIG
@ -5999,6 +6094,12 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
ssl->options.haveECC = 1;
}
#endif
#ifdef HAVE_LIBOQS
else if (cert->keyOID == FALCON_LEVEL1k ||
cert->keyOID == FALCON_LEVEL5k) {
ssl->options.haveFalconSig = 1;
}
#endif
#else
ssl->options.haveECC = ssl->options.haveECDSAsig;
#endif
@ -6019,6 +6120,12 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
ctx->haveECC = 1;
}
#endif
#ifdef HAVE_LIBOQS
else if (cert->keyOID == FALCON_LEVEL1k ||
cert->keyOID == FALCON_LEVEL5k) {
ctx->haveFalconSig = 1;
}
#endif
#else
ctx->haveECC = ctx->haveECDSAsig;
#endif
@ -6126,6 +6233,27 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
}
break;
#endif /* HAVE_ED448 */
#ifdef HAVE_LIBOQS
case FALCON_LEVEL1k:
case FALCON_LEVEL5k:
/* Falcon is fixed key size */
keySz = FALCON_MAX_KEY_SIZE;
if (ssl && !ssl->options.verifyNone) {
if (ssl->options.minFalconKeySz < 0 ||
keySz < (int)ssl->options.minFalconKeySz) {
ret = FALCON_KEY_SIZE_E;
WOLFSSL_MSG("Certificate Falcon key size error");
}
}
else if (ctx && !ctx->verifyNone) {
if (ctx->minFalconKeySz < 0 ||
keySz < (int)ctx->minFalconKeySz) {
ret = FALCON_KEY_SIZE_E;
WOLFSSL_MSG("Certificate Falcon key size error");
}
}
break;
#endif /* HAVE_LIBOQS */
default:
WOLFSSL_MSG("No key size check done on certificate");
@ -6198,7 +6326,8 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
InitSuites(ssl->suites, ssl->version, keySz, haveRSA,
havePSK, ssl->options.haveDH, ssl->options.haveECDSAsig,
ssl->options.haveECC, ssl->options.haveStaticECC,
ssl->options.haveAnon, ssl->options.side);
ssl->options.haveFalconSig, ssl->options.haveAnon,
ssl->options.side);
}
return WOLFSSL_SUCCESS;
@ -15999,7 +16128,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
ssl->options.haveDH, ssl->options.haveECDSAsig,
ssl->options.haveECC, ssl->options.haveStaticECC,
ssl->options.haveAnon, ssl->options.side);
ssl->options.haveFalconSig, ssl->options.haveAnon,
ssl->options.side);
}
#ifdef OPENSSL_EXTRA
/**
@ -16051,7 +16181,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
ssl->options.haveDH, ssl->options.haveECDSAsig,
ssl->options.haveECC, ssl->options.haveStaticECC,
ssl->options.haveAnon, ssl->options.side);
ssl->options.haveFalconSig, ssl->options.haveAnon,
ssl->options.side);
}
const char* wolfSSL_get_psk_identity_hint(const WOLFSSL* ssl)
@ -28284,7 +28415,8 @@ long wolfSSL_set_options(WOLFSSL* ssl, long op)
InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
ssl->options.haveDH, ssl->options.haveECDSAsig,
ssl->options.haveECC, ssl->options.haveStaticECC,
ssl->options.haveAnon, ssl->options.side);
ssl->options.haveFalconSig, ssl->options.haveAnon,
ssl->options.side);
return ssl->options.mask;
}
@ -31569,6 +31701,12 @@ const WOLFSSL_ObjectInfo wolfssl_object_info[] = {
#ifdef HAVE_ED25519
{ NID_ED25519, ED25519k, oidKeyType, "ED25519", "ED25519"},
#endif
#ifdef HAVE_LIBOQS
{ CTC_FALCON_LEVEL1, FALCON_LEVEL1k, oidKeyType, "Falcon Level 1",
"Falcon Level 1"},
{ CTC_FALCON_LEVEL5, FALCON_LEVEL5k, oidKeyType, "Falcon Level 5",
"Falcon Level 5"},
#endif
/* oidCurveType */
#ifdef HAVE_ECC
@ -36266,7 +36404,7 @@ struct WOLFSSL_HashSigInfo {
{ sha224_mac, rsa_sa_algo, CTC_SHA224wRSA },
#endif
#ifndef NO_SHA
{ sha_mac, rsa_sa_algo, CTC_SHAwRSA },
{ sha_mac, rsa_sa_algo, CTC_SHAwRSA },
#endif
#ifdef WC_RSA_PSS
#ifndef NO_SHA256
@ -36297,18 +36435,22 @@ struct WOLFSSL_HashSigInfo {
{ sha224_mac, ecc_dsa_sa_algo, CTC_SHA224wECDSA },
#endif
#ifndef NO_SHA
{ sha_mac, ecc_dsa_sa_algo, CTC_SHAwECDSA },
{ sha_mac, ecc_dsa_sa_algo, CTC_SHAwECDSA },
#endif
#endif
#ifdef HAVE_ED25519
{ no_mac, ed25519_sa_algo, CTC_ED25519 },
#endif
#ifdef HAVE_ED25519
{ no_mac, ed448_sa_algo, CTC_ED448 },
#ifdef HAVE_ED448
{ no_mac, ed448_sa_algo, CTC_ED448 },
#endif
#ifdef HAVE_LIBOQS
{ no_mac, falcon_level1_sa_algo, CTC_FALCON_LEVEL1 },
{ no_mac, falcon_level5_sa_algo, CTC_FALCON_LEVEL5 },
#endif
#ifndef NO_DSA
#ifndef NO_SHA
{ sha_mac, dsa_sa_algo, CTC_SHAwDSA },
{ sha_mac, dsa_sa_algo, CTC_SHAwDSA },
#endif
#endif
};

View File

@ -5136,7 +5136,8 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx,
WOLFSSL_ENTER("SendTls13CertificateRequest");
if (ssl->options.side == WOLFSSL_SERVER_END)
InitSuitesHashSigAlgo(ssl->suites, 1, 1, 0, 1, ssl->buffers.keySz);
InitSuitesHashSigAlgo(ssl->suites, 1, 1, 1,
0, 1, ssl->buffers.keySz);
ext = TLSX_Find(ssl->extensions, TLSX_SIGNATURE_ALGORITHMS);
if (ext == NULL)
@ -5207,7 +5208,7 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx,
#ifndef NO_CERTS
#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
defined(HAVE_ED448)
defined(HAVE_ED448) || defined(HAVE_LIBOQS)
/* Encode the signature algorithm into buffer.
*
* hashalgo The hash algorithm.
@ -5245,6 +5246,16 @@ static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output)
output[0] = rsa_pss_sa_algo;
output[1] = hashAlgo;
break;
#endif
#ifdef HAVE_LIBOQS
case falcon_level1_sa_algo:
output[0] = FALCON_LEVEL1_SA_MAJOR;
output[1] = FALCON_LEVEL1_SA_MINOR;
break;
case falcon_level5_sa_algo:
output[0] = FALCON_LEVEL5_SA_MAJOR;
output[1] = FALCON_LEVEL5_SA_MINOR;
break;
#endif
default:
break;
@ -5289,6 +5300,23 @@ static WC_INLINE int DecodeTls13SigAlg(byte* input, byte* hashAlgo,
else
ret = INVALID_PARAMETER;
break;
#ifdef HAVE_LIBOQS
case OQS_SA_MAJOR:
if (input[1] == FALCON_LEVEL1_SA_MINOR) {
*hsType = falcon_level1_sa_algo;
/* Hash performed as part of sign/verify operation. */
*hashAlgo = sha512_mac;
} else
if (input[1] == FALCON_LEVEL5_SA_MINOR) {
*hsType = falcon_level1_sa_algo;
/* Hash performed as part of sign/verify operation. */
*hashAlgo = sha512_mac;
}
else {
ret = INVALID_PARAMETER;
}
break;
#endif
default:
*hashAlgo = input[0];
*hsType = input[1];
@ -5906,7 +5934,7 @@ static int SendTls13Certificate(WOLFSSL* ssl)
}
#if (!defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
defined(HAVE_ED448)) && \
defined(HAVE_ED448) || defined(HAVE_LIBOQS)) && \
(!defined(NO_WOLFSSL_SERVER) || !defined(WOLFSSL_NO_CLIENT_AUTH))
typedef struct Scv13Args {
byte* output; /* not allocated */
@ -6050,6 +6078,24 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
#ifdef HAVE_ED448
else if (ssl->hsType == DYNAMIC_TYPE_ED448)
args->sigAlgo = ed448_sa_algo;
#endif
#ifdef HAVE_LIBOQS
else if (ssl->hsType == DYNAMIC_TYPE_FALCON) {
falcon_key* fkey = (falcon_key*)ssl->hsKey;
byte level = 0;
if (wc_falcon_get_level(fkey, &level) != 0) {
ERROR_OUT(ALGO_ID_E, exit_scv);
}
if (level == 1) {
args->sigAlgo = falcon_level1_sa_algo;
}
else if (level == 5) {
args->sigAlgo = falcon_level1_sa_algo;
}
else {
ERROR_OUT(ALGO_ID_E, exit_scv);
}
}
#endif
else {
ERROR_OUT(ALGO_ID_E, exit_scv);
@ -6127,6 +6173,11 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
sig->length = ED448_SIG_SIZE;
}
#endif /* HAVE_ED448 */
#ifdef HAVE_LIBOQS
if (ssl->hsType == DYNAMIC_TYPE_FALCON) {
sig->length = FALCON_MAX_SIG_SIZE;
}
#endif /* HAVE_LIBOQS */
/* Advance state and proceed */
ssl->options.asyncState = TLS_ASYNC_DO;
@ -6178,6 +6229,15 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
args->length = (word16)sig->length;
}
#endif
#ifdef HAVE_LIBOQS
if (ssl->hsType == DYNAMIC_TYPE_FALCON) {
ret = wc_falcon_sign_msg(args->sigData, args->sigDataSz,
args->verify + HASH_SIG_SIZE +
VERIFY_HEADER, (word32*)&sig->length,
(falcon_key*)ssl->hsKey);
args->length = (word16)sig->length;
}
#endif /* HAVE_LIBOQS */
#ifndef NO_RSA
if (ssl->hsType == DYNAMIC_TYPE_RSA) {
ret = RsaSign(ssl, sig->buffer, (word32)sig->length,
@ -6488,6 +6548,19 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
goto exit_dcv;
}
#endif
#ifdef HAVE_LIBOQS
if (args->sigAlgo == falcon_level1_sa_algo && !ssl->peerFalconKeyPresent) {
WOLFSSL_MSG("Peer sent Falcon Level 1 sig but different cert");
ret = SIG_VERIFY_E;
goto exit_dcv;
}
if (args->sigAlgo == falcon_level5_sa_algo && !ssl->peerFalconKeyPresent) {
WOLFSSL_MSG("Peer sent Falcon Level 5 sig but different cert");
ret = SIG_VERIFY_E;
goto exit_dcv;
}
#endif
#ifndef NO_RSA
if (args->sigAlgo == rsa_sa_algo) {
WOLFSSL_MSG("Peer sent PKCS#1.5 algo but not in certificate");
@ -6558,6 +6631,20 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
ret = 0;
}
#endif
#ifdef HAVE_LIBOQS
if (ssl->peerFalconKeyPresent) {
WOLFSSL_MSG("Doing Falcon peer cert verify");
args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap,
DYNAMIC_TYPE_SIGNATURE);
if (args->sigData == NULL) {
ERROR_OUT(MEMORY_E, exit_dcv);
}
CreateSigData(ssl, args->sigData, &args->sigDataSz, 1);
ret = 0;
}
#endif
/* Advance state and proceed */
ssl->options.asyncState = TLS_ASYNC_DO;
@ -6638,6 +6725,21 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
}
}
#endif
#ifdef HAVE_LIBOQS
if (ssl->peerFalconKeyPresent) {
int res = 0;
WOLFSSL_MSG("Doing Falcon peer cert verify");
ret = wc_falcon_verify_msg(input + args->idx, args->sz,
args->sigData, args->sigDataSz,
&res, ssl->peerFalconKey);
if ((ret >= 0) && (res == 1)) {
FreeKey(ssl, DYNAMIC_TYPE_FALCON,
(void**)&ssl->peerFalconKey);
ssl->peerFalconKeyPresent = 0;
}
}
#endif
/* Check for error */
if (ret != 0) {
@ -8006,13 +8108,12 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
#endif
#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
defined(HAVE_ED448)
defined(HAVE_ED448) || defined(HAVE_LIBOQS)
case certificate_verify:
WOLFSSL_MSG("processing certificate verify");
ret = DoTls13CertificateVerify(ssl, input, inOutIdx, size);
break;
#endif /* !NO_RSA || HAVE_ECC */
#endif
case finished:
WOLFSSL_MSG("processing finished");
ret = DoTls13Finished(ssl, input, inOutIdx, size, totalSz, NO_SNIFF);
@ -8444,8 +8545,9 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
case FIRST_REPLY_THIRD:
#if (!defined(NO_CERTS) && (!defined(NO_RSA) || defined(HAVE_ECC) || \
defined(HAVE_ED25519) || defined(HAVE_ED448))) && \
(!defined(NO_WOLFSSL_SERVER) || !defined(WOLFSSL_NO_CLIENT_AUTH))
defined(HAVE_ED25519) || defined(HAVE_ED448) || \
defined(HAVE_LIBOQS))) && (!defined(NO_WOLFSSL_SERVER) || \
!defined(WOLFSSL_NO_CLIENT_AUTH))
if (!ssl->options.resuming && ssl->options.sendVerify) {
ssl->error = SendTls13CertificateVerify(ssl);
if (ssl->error != 0) {
@ -9003,7 +9105,8 @@ void wolfSSL_set_psk_client_cs_callback(WOLFSSL* ssl,
InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
ssl->options.haveDH, ssl->options.haveECDSAsig,
ssl->options.haveECC, ssl->options.haveStaticECC,
ssl->options.haveAnon, ssl->options.side);
ssl->options.haveFalconSig, ssl->options.haveAnon,
ssl->options.side);
}
/* Set the PSK callback that returns the cipher suite for a client to use
@ -9053,7 +9156,8 @@ void wolfSSL_set_psk_client_tls13_callback(WOLFSSL* ssl,
InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
ssl->options.haveDH, ssl->options.haveECDSAsig,
ssl->options.haveECC, ssl->options.haveStaticECC,
ssl->options.haveAnon, ssl->options.side);
ssl->options.haveFalconSig, ssl->options.haveAnon,
ssl->options.side);
}
/* Set the PSK callback that returns the cipher suite for a server to use
@ -9100,7 +9204,8 @@ void wolfSSL_set_psk_server_tls13_callback(WOLFSSL* ssl,
InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
ssl->options.haveDH, ssl->options.haveECDSAsig,
ssl->options.haveECC, ssl->options.haveStaticECC,
ssl->options.haveAnon, ssl->options.side);
ssl->options.haveFalconSig, ssl->options.haveAnon,
ssl->options.side);
}
/* Get name of first supported cipher suite that uses the hash indicated.
@ -9387,7 +9492,7 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
case TLS13_CERT_SENT :
#if !defined(NO_CERTS) && (!defined(NO_RSA) || defined(HAVE_ECC) || \
defined(HAVE_ED25519) || defined(HAVE_ED448))
defined(HAVE_ED25519) || defined(HAVE_ED448) || defined(HAVE_LIBOQS))
if (!ssl->options.resuming && ssl->options.sendVerify) {
if ((ssl->error = SendTls13CertificateVerify(ssl)) != 0) {
WOLFSSL_ERROR(ssl->error);

View File

@ -131,6 +131,10 @@ ASN Options:
#include <wolfssl/wolfcrypt/curve448.h>
#endif
#ifdef HAVE_LIBOQS
#include <wolfssl/wolfcrypt/falcon.h>
#endif
#ifdef WOLFSSL_QNX_CAAM
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
#endif
@ -3811,6 +3815,13 @@ static word32 SetBitString16Bit(word16 val, byte* output)
#ifdef HAVE_ED448
static const byte sigEd448Oid[] = {43, 101, 113};
#endif /* HAVE_ED448 */
#ifdef HAVE_LIBOQS
/* Falcon Level 1: 1 3 9999 3 1 */
static const byte sigFalcon_Level1Oid[] = {43, 206, 15, 3, 1};
/* Falcon Level 5: 1 3 9999 3 4 */
static const byte sigFalcon_Level5Oid[] = {43, 206, 15, 3, 4};
#endif /* HAVE_LIBOQS */
/* keyType */
#ifndef NO_DSA
@ -3837,6 +3848,13 @@ static word32 SetBitString16Bit(word16 val, byte* output)
#ifndef NO_DH
static const byte keyDhOid[] = {42, 134, 72, 134, 247, 13, 1, 3, 1};
#endif /* !NO_DH */
#ifdef HAVE_LIBOQS
/* Falcon Level 1: 1 3 9999 3 1 */
static const byte keyFalcon_Level1Oid[] = {43, 206, 15, 3, 1};
/* Falcon Level 5: 1 3 9999 3 4 */
static const byte keyFalcon_Level5Oid[] = {43, 206, 15, 3, 4};
#endif /* HAVE_LIBOQS */
/* curveType */
#ifdef HAVE_ECC
@ -4249,6 +4267,16 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz)
*oidSz = sizeof(sigEd448Oid);
break;
#endif
#ifdef HAVE_LIBOQS
case CTC_FALCON_LEVEL1:
oid = sigFalcon_Level1Oid;
*oidSz = sizeof(sigFalcon_Level1Oid);
break;
case CTC_FALCON_LEVEL5:
oid = sigFalcon_Level5Oid;
*oidSz = sizeof(sigFalcon_Level5Oid);
break;
#endif
default:
break;
}
@ -4304,6 +4332,16 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz)
*oidSz = sizeof(keyDhOid);
break;
#endif /* !NO_DH */
#ifdef HAVE_LIBOQS
case FALCON_LEVEL1k:
oid = keyFalcon_Level1Oid;
*oidSz = sizeof(keyFalcon_Level1Oid);
break;
case FALCON_LEVEL5k:
oid = keyFalcon_Level5Oid;
*oidSz = sizeof(keyFalcon_Level5Oid);
break;
#endif
default:
break;
}
@ -5510,7 +5548,7 @@ static const ASNItem pkcs8KeyASN[] = {
#define pkcs8KeyASN_Length (sizeof(pkcs8KeyASN) / sizeof(ASNItem))
#endif
/* Remove PKCS #8 header around an RSA, ECDSA, Ed25519 or Ed448 key.
/* Remove PKCS #8 header around an RSA, ECDSA, Ed25519, Ed448, or Falcon key.
*
* @param [in] input Buffer holding BER data.
* @param [in, out] inOutIdx On in, start of PKCS #8 encoding.
@ -6132,6 +6170,62 @@ int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz,
}
else
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT && !NO_ASN_CRYPT */
#if defined(HAVE_LIBOQS)
if ((ks == FALCON_LEVEL1k) || (ks == FALCON_LEVEL5k)) {
#ifdef WOLFSSL_SMALL_STACK
falcon_key* key_pair = NULL;
#else
falcon_key key_pair[1];
#endif
word32 keyIdx = 0;
#ifdef WOLFSSL_SMALL_STACK
key_pair = (falcon_key*)XMALLOC(sizeof(falcon_key), NULL,
DYNAMIC_TYPE_FALCON);
if (key_pair == NULL)
return MEMORY_E;
#endif
ret = wc_falcon_init(key_pair);
if (ret < 0) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(key_pair, NULL, DYNAMIC_TYPE_FALCON);
#endif
return ret;
}
if (ks == FALCON_LEVEL1k) {
ret = wc_falcon_set_level(key_pair, 1);
}
else if (ks == FALCON_LEVEL5k) {
ret = wc_falcon_set_level(key_pair, 5);
}
if (ret < 0) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(key_pair, NULL, DYNAMIC_TYPE_FALCON);
#endif
return ret;
}
if ((ret = wc_Falcon_PrivateKeyDecode(privKey, &keyIdx, key_pair,
privKeySz)) == 0) {
WOLFSSL_MSG("Checking Falcon_ key pair");
keyIdx = 0;
if ((ret = wc_falcon_import_public(pubKey, pubKeySz,
key_pair)) == 0) {
/* public and private extracted successfully no check if is
* a pair and also do sanity checks on key. wc_ecc_check_key
* checks that private * base generator equals pubkey */
if ((ret = wc_falcon_check_key(key_pair)) == 0)
ret = 1;
}
}
wc_falcon_free(key_pair);
#ifdef WOLFSSL_SMALL_STACK
XFREE(key_pair, NULL, DYNAMIC_TYPE_FALCON);
#endif
}
else
#endif /* HAVE_LIBOQS */
{
ret = 0;
}
@ -6433,9 +6527,43 @@ int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz,
XFREE(ed448, heap, DYNAMIC_TYPE_TMP_BUFFER);
}
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT && !NO_ASN_CRYPT */
#if defined(HAVE_LIBOQS)
if (*algoID == 0) {
falcon_key *falcon = (falcon_key *)XMALLOC(sizeof(*falcon), heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (falcon == NULL)
return MEMORY_E;
/* if flag is not set then is neither RSA or ECC key that could be
* found */
if (wc_falcon_init(falcon) != 0) {
tmpIdx = 0;
if (wc_falcon_set_level(falcon, 1) == 0) {
if (wc_Falcon_PrivateKeyDecode(key, &tmpIdx, falcon, keySz)
== 0) {
*algoID = FALCON_LEVEL1k;
}
else {
WOLFSSL_MSG("Not Falcon Level 1 DER key");
}
}
else if (wc_falcon_set_level(falcon, 5) == 0) {
if (wc_Falcon_PrivateKeyDecode(key, &tmpIdx, falcon, keySz)
== 0) {
*algoID = FALCON_LEVEL5k;
}
else {
WOLFSSL_MSG("Not Falcon Level 5 DER key");
}
}
else {
WOLFSSL_MSG("GetKeyOID falcon initialization failed");
}
wc_falcon_free(falcon);
}
XFREE(falcon, heap, DYNAMIC_TYPE_TMP_BUFFER);
}
#endif /* HAVE_LIBOQS */
/* if flag is not set then this is not a key that we understand. */
if (*algoID == 0) {
WOLFSSL_MSG("Bad key DER or compile options");
return BAD_FUNC_ARG;
@ -9497,7 +9625,7 @@ static int GetCertHeader(DecodedCert* cert)
}
#endif
#if defined(HAVE_ED25519) || defined(HAVE_ED448)
#if defined(HAVE_ED25519) || defined(HAVE_ED448) || defined(HAVE_LIBOQS)
/* Store the key data under the BIT_STRING in dynamicly allocated data.
*
* @param [in, out] cert Certificate object.
@ -9912,6 +10040,16 @@ static int GetCertKey(DecodedCert* cert, const byte* source, word32* inOutIdx,
ret = StoreKey(cert, source, &srcIdx, maxIdx);
break;
#endif /* HAVE_ED448 */
#ifdef HAVE_LIBOQS
case FALCON_LEVEL1k:
cert->pkCurveOID = FALCON_LEVEL1k;
ret = StoreKey(cert, source, &srcIdx, maxIdx);
break;
case FALCON_LEVEL5k:
cert->pkCurveOID = FALCON_LEVEL5k;
ret = StoreKey(cert, source, &srcIdx, maxIdx);
break;
#endif /* HAVE_LIBOQS */
#ifndef NO_DSA
case DSAk:
cert->publicKey = source + pubIdx;
@ -12474,6 +12612,10 @@ static WC_INLINE int IsSigAlgoECC(int algoOID)
#ifdef HAVE_CURVE448
|| (algoOID == X448k)
#endif
#ifdef HAVE_LIBOQS
|| (algoOID == FALCON_LEVEL1k)
|| (algoOID == FALCON_LEVEL5k)
#endif
);
}
@ -12720,33 +12862,47 @@ void FreeSignatureCtx(SignatureCtx* sigCtx)
#ifndef NO_RSA
case RSAk:
wc_FreeRsaKey(sigCtx->key.rsa);
XFREE(sigCtx->key.ptr, sigCtx->heap, DYNAMIC_TYPE_RSA);
XFREE(sigCtx->key.rsa, sigCtx->heap, DYNAMIC_TYPE_RSA);
sigCtx->key.rsa = NULL;
break;
#endif /* !NO_RSA */
#ifndef NO_DSA
case DSAk:
wc_FreeDsaKey(sigCtx->key.dsa);
XFREE(sigCtx->key.dsa, sigCtx->heap, DYNAMIC_TYPE_DSA);
sigCtx->key.dsa = NULL;
break;
#endif
#ifdef HAVE_ECC
case ECDSAk:
wc_ecc_free(sigCtx->key.ecc);
XFREE(sigCtx->key.ecc, sigCtx->heap, DYNAMIC_TYPE_ECC);
sigCtx->key.ecc = NULL;
break;
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
case ED25519k:
wc_ed25519_free(sigCtx->key.ed25519);
XFREE(sigCtx->key.ed25519, sigCtx->heap, DYNAMIC_TYPE_ED25519);
sigCtx->key.ed25519 = NULL;
break;
#endif /* HAVE_ED25519 */
#ifdef HAVE_ED448
case ED448k:
wc_ed448_free(sigCtx->key.ed448);
XFREE(sigCtx->key.ed448, sigCtx->heap, DYNAMIC_TYPE_ED448);
sigCtx->key.ed448 = NULL;
break;
#endif /* HAVE_ED448 */
#ifdef HAVE_LIBOQS
case FALCON_LEVEL1k:
case FALCON_LEVEL5k:
wc_falcon_free(sigCtx->key.falcon);
XFREE(sigCtx->key.falcon, sigCtx->heap,
DYNAMIC_TYPE_FALCON);
sigCtx->key.falcon = NULL;
break;
#endif /* HAVE_LIBOQS */
default:
break;
} /* switch (keyOID) */
@ -12884,6 +13040,13 @@ static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID,
*/
break;
#endif
#ifdef HAVE_LIBOQS
case CTC_FALCON_LEVEL1:
case CTC_FALCON_LEVEL5:
/* Hashes done in signing operation. */
break;
#endif
default:
ret = HASH_TYPE_E;
WOLFSSL_MSG("Hash for Signature has unsupported type");
@ -13169,6 +13332,56 @@ static int ConfirmSignature(SignatureCtx* sigCtx,
#endif
break;
}
#endif
#if defined(HAVE_LIBOQS)
case FALCON_LEVEL1k:
{
sigCtx->verify = 0;
sigCtx->key.falcon =
(falcon_key*)XMALLOC(sizeof(falcon_key),
sigCtx->heap,
DYNAMIC_TYPE_FALCON);
if (sigCtx->key.falcon == NULL) {
ERROR_OUT(MEMORY_E, exit_cs);
}
if ((ret = wc_falcon_init(sigCtx->key.falcon)) < 0) {
goto exit_cs;
}
if ((ret = wc_falcon_set_level(sigCtx->key.falcon, 1))
< 0) {
goto exit_cs;
}
if ((ret = wc_falcon_import_public(key, keySz,
sigCtx->key.falcon)) < 0) {
WOLFSSL_MSG("ASN Key import error Falcon Level 1");
goto exit_cs;
}
break;
}
case FALCON_LEVEL5k:
{
sigCtx->verify = 0;
sigCtx->key.falcon =
(falcon_key*)XMALLOC(sizeof(falcon_key),
sigCtx->heap,
DYNAMIC_TYPE_FALCON);
if (sigCtx->key.falcon == NULL) {
ERROR_OUT(MEMORY_E, exit_cs);
}
if ((ret = wc_falcon_init(sigCtx->key.falcon)) < 0) {
goto exit_cs;
}
if ((ret = wc_falcon_set_level(sigCtx->key.falcon, 5))
< 0) {
goto exit_cs;
}
if ((ret = wc_falcon_import_public(key, keySz,
sigCtx->key.falcon)) < 0) {
WOLFSSL_MSG("ASN Key import error Falcon Level 5");
goto exit_cs;
}
break;
}
#endif
default:
WOLFSSL_MSG("Verify Key type unknown");
@ -13280,6 +13493,16 @@ static int ConfirmSignature(SignatureCtx* sigCtx,
NULL, 0);
break;
}
#endif
#if defined(HAVE_LIBOQS)
case FALCON_LEVEL1k:
case FALCON_LEVEL5k:
{
ret = wc_falcon_verify_msg(sig, sigSz, buf, bufSz,
&sigCtx->verify,
sigCtx->key.falcon);
break;
}
#endif
default:
break;
@ -13393,6 +13616,30 @@ static int ConfirmSignature(SignatureCtx* sigCtx,
break;
}
#endif /* HAVE_ED448 */
#ifdef HAVE_LIBOQS
case FALCON_LEVEL1k:
{
if (sigCtx->verify == 1) {
ret = 0;
}
else {
WOLFSSL_MSG("FALCON_LEVEL1 Verify didn't match");
ret = ASN_SIG_CONFIRM_E;
}
break;
}
case FALCON_LEVEL5k:
{
if (sigCtx->verify == 1) {
ret = 0;
}
else {
WOLFSSL_MSG("FALCON_LEVEL5 Verify didn't match");
ret = ASN_SIG_CONFIRM_E;
}
break;
}
#endif /* HAVE_LIBOQS */
default:
break;
} /* switch (keyOID) */
@ -18430,6 +18677,12 @@ wcchar END_PUB_KEY = "-----END PUBLIC KEY-----";
wcchar BEGIN_EDDSA_PRIV = "-----BEGIN EDDSA PRIVATE KEY-----";
wcchar END_EDDSA_PRIV = "-----END EDDSA PRIVATE KEY-----";
#endif
#if defined(HAVE_LIBOQS)
wcchar BEGIN_FALCON_LEVEL1_PRIV = "-----BEGIN FALCON_LEVEL1 PRIVATE KEY-----";
wcchar END_FALCON_LEVEL1_PRIV = "-----END FALCON_LEVEL1 PRIVATE KEY-----";
wcchar BEGIN_FALCON_LEVEL5_PRIV = "-----BEGIN FALCON_LEVEL5 PRIVATE KEY-----";
wcchar END_FALCON_LEVEL5_PRIV = "-----END FALCON_LEVEL5 PRIVATE KEY-----";
#endif
const int pem_struct_min_sz = XSTR_SIZEOF("-----BEGIN X509 CRL-----"
"-----END X509 CRL-----");
@ -18524,6 +18777,18 @@ int wc_PemGetHeaderFooter(int type, const char** header, const char** footer)
ret = 0;
break;
#endif
#ifdef HAVE_LIBOQS
case FALCON_LEVEL1_TYPE:
if (header) *header = BEGIN_FALCON_LEVEL1_PRIV;
if (footer) *footer = END_FALCON_LEVEL1_PRIV;
ret = 0;
break;
case FALCON_LEVEL5_TYPE:
if (header) *header = BEGIN_FALCON_LEVEL5_PRIV;
if (footer) *footer = END_FALCON_LEVEL5_PRIV;
ret = 0;
break;
#endif
case PUBLICKEY_TYPE:
case ECC_PUBLICKEY_TYPE:
if (header) *header = BEGIN_PUB_KEY;
@ -20672,6 +20937,50 @@ int wc_Ed448PublicKeyToDer(ed448_key* key, byte* output, word32 inLen,
}
#endif /* HAVE_ED448 && HAVE_ED448_KEY_EXPORT */
#if defined(HAVE_LIBOQS)
/* Encode the public part of an Falcon key in DER.
*
* Pass NULL for output to get the size of the encoding.
*
* @param [in] key Falcon key object.
* @param [out] output Buffer to put encoded data in.
* @param [in] outLen Size of buffer in bytes.
* @param [in] withAlg Whether to use SubjectPublicKeyInfo format.
* @return Size of encoded data in bytes on success.
* @return BAD_FUNC_ARG when key is NULL.
* @return MEMORY_E when dynamic memory allocation failed.
*/
int wc_Falcon_PublicKeyToDer(falcon_key* key, byte* output, word32 inLen,
int withAlg)
{
int ret;
byte pubKey[FALCON_MAX_PUB_KEY_SIZE];
word32 pubKeyLen = (word32)sizeof(pubKey);
int keytype = 0;
if (key == NULL || output == NULL) {
return BAD_FUNC_ARG;
}
if (key->level == 1) {
keytype = FALCON_LEVEL1k;
}
else if (key->level == 5) {
keytype = FALCON_LEVEL5k;
}
else {
return BAD_FUNC_ARG;
}
ret = wc_falcon_export_public(key, pubKey, &pubKeyLen);
if (ret == 0) {
ret = SetAsymKeyDerPublic(pubKey, pubKeyLen, output, inLen, keytype,
withAlg);
}
return ret;
}
#endif /* HAVE_LIBOQS */
#ifdef WOLFSSL_CERT_GEN
@ -22647,7 +22956,7 @@ static int SetValidity(byte* before, byte* after, int daysValid)
/* encode info from cert into DER encoded format */
static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
WC_RNG* rng, DsaKey* dsaKey, ed25519_key* ed25519Key,
ed448_key* ed448Key)
ed448_key* ed448Key, falcon_key* falconKey)
{
int ret;
@ -22656,7 +22965,7 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
/* make sure at least one key type is provided */
if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL &&
dsaKey == NULL && ed448Key == NULL) {
dsaKey == NULL && ed448Key == NULL && falconKey == NULL) {
return PUBLIC_KEY_E;
}
@ -22732,6 +23041,18 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
}
#endif
#if defined(HAVE_LIBOQS)
if ((cert->keyType == FALCON_LEVEL1_KEY) ||
(cert->keyType == FALCON_LEVEL5_KEY)) {
if (falconKey == NULL)
return PUBLIC_KEY_E;
der->publicKeySz =
wc_Falcon_PublicKeyToDer(falconKey, der->publicKey,
(word32)sizeof(der->publicKey), 1);
}
#endif
if (der->publicKeySz <= 0)
return PUBLIC_KEY_E;
@ -23100,8 +23421,8 @@ static int WriteCertBody(DerCert* der, byte* buf)
/* Make RSA signature from buffer (sz), write to sig (sigSz) */
static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, int sz,
byte* sig, int sigSz, RsaKey* rsaKey, ecc_key* eccKey,
ed25519_key* ed25519Key, ed448_key* ed448Key, WC_RNG* rng, int sigAlgoType,
void* heap)
ed25519_key* ed25519Key, ed448_key* ed448Key, falcon_key* falconKey,
WC_RNG* rng, int sigAlgoType, void* heap)
{
int digestSz = 0, typeH = 0, ret = 0;
@ -23115,6 +23436,7 @@ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, int sz,
(void)eccKey;
(void)ed25519Key;
(void)ed448Key;
(void)falconKey;
(void)rng;
(void)heap;
@ -23196,6 +23518,16 @@ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, int sz,
ret = outSz;
}
#endif /* HAVE_ED448 && HAVE_ED448_SIGN */
#if defined(HAVE_LIBOQS)
if (!rsaKey && !eccKey && !ed25519Key && !ed448Key && falconKey) {
word32 outSz = sigSz;
ret = wc_falcon_sign_msg(buf, sz, sig, &outSz, falconKey);
if (ret == 0)
ret = outSz;
}
#endif /* HAVE_LIBOQS */
break;
}
@ -23361,7 +23693,7 @@ int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz,
static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng,
DsaKey* dsaKey, ed25519_key* ed25519Key,
ed448_key* ed448Key)
ed448_key* ed448Key, falcon_key* falconKey)
{
#ifndef WOLFSSL_ASN_TEMPLATE
int ret;
@ -23384,6 +23716,12 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
cert->keyType = ED25519_KEY;
else if (ed448Key)
cert->keyType = ED448_KEY;
#ifdef HAVE_LIBOQS
else if ((falconKey != NULL) && (falconKey->level == 1))
cert->keyType = FALCON_LEVEL1_KEY;
else if ((falconKey != NULL) && (falconKey->level == 5))
cert->keyType = FALCON_LEVEL5_KEY;
#endif
else
return BAD_FUNC_ARG;
@ -23394,7 +23732,7 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
#endif
ret = EncodeCert(cert, der, rsaKey, eccKey, rng, dsaKey, ed25519Key,
ed448Key);
ed448Key, falconKey);
if (ret == 0) {
if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
ret = BUFFER_E;
@ -23438,6 +23776,12 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
else if (ed448Key) {
cert->keyType = ED448_KEY;
}
else if ((falconKey != NULL) && (falconKey->level == 1)) {
cert->keyType = FALCON_LEVEL1_KEY;
}
else if ((falconKey != NULL) && (falconKey->level == 5)) {
cert->keyType = FALCON_LEVEL5_KEY;
}
else {
ret = BAD_FUNC_ARG;
}
@ -23641,11 +23985,12 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
void* key, WC_RNG* rng)
{
RsaKey* rsaKey = NULL;
DsaKey* dsaKey = NULL;
ecc_key* eccKey = NULL;
ed25519_key* ed25519Key = NULL;
ed448_key* ed448Key = NULL;
RsaKey* rsaKey = NULL;
DsaKey* dsaKey = NULL;
ecc_key* eccKey = NULL;
ed25519_key* ed25519Key = NULL;
ed448_key* ed448Key = NULL;
falcon_key* falconKey = NULL;
if (keyType == RSA_TYPE)
rsaKey = (RsaKey*)key;
@ -23657,16 +24002,21 @@ int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
ed25519Key = (ed25519_key*)key;
else if (keyType == ED448_TYPE)
ed448Key = (ed448_key*)key;
else if (keyType == FALCON_LEVEL1_TYPE)
falconKey = (falcon_key*)key;
else if (keyType == FALCON_LEVEL5_TYPE)
falconKey = (falcon_key*)key;
return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, dsaKey,
ed25519Key, ed448Key);
ed25519Key, ed448Key, falconKey);
}
/* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,
ecc_key* eccKey, WC_RNG* rng)
{
return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, NULL,
NULL);
NULL, NULL);
}
#ifdef WOLFSSL_CERT_REQ
@ -23753,18 +24103,20 @@ static int SetReqAttrib(byte* output, char* pw, int pwPrintableString,
/* encode info from cert into DER encoded format */
static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
DsaKey* dsaKey, ecc_key* eccKey,
ed25519_key* ed25519Key, ed448_key* ed448Key)
ed25519_key* ed25519Key, ed448_key* ed448Key,
falcon_key* falconKey)
{
(void)eccKey;
(void)ed25519Key;
(void)ed448Key;
(void)falconKey;
if (cert == NULL || der == NULL)
return BAD_FUNC_ARG;
if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL &&
dsaKey == NULL && ed448Key == NULL) {
return PUBLIC_KEY_E;
dsaKey == NULL && ed448Key == NULL && falconKey == NULL) {
return PUBLIC_KEY_E;
}
/* init */
@ -23845,6 +24197,16 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
(word32)sizeof(der->publicKey), 1);
}
#endif
#if defined(HAVE_LIBOQS)
if ((cert->keyType == FALCON_LEVEL1_KEY) ||
(cert->keyType == FALCON_LEVEL5_KEY)) {
if (falconKey == NULL)
return PUBLIC_KEY_E;
der->publicKeySz = wc_Falcon_PublicKeyToDer(falconKey,
der->publicKey, (word32)sizeof(der->publicKey), 1);
}
#endif
if (der->publicKeySz <= 0)
return PUBLIC_KEY_E;
@ -24069,7 +24431,8 @@ static const ASNItem certReqBodyASN[] = {
static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
RsaKey* rsaKey, DsaKey* dsaKey, ecc_key* eccKey,
ed25519_key* ed25519Key, ed448_key* ed448Key)
ed25519_key* ed25519Key, ed448_key* ed448Key,
falcon_key* falconKey)
{
#ifndef WOLFSSL_ASN_TEMPLATE
int ret;
@ -24089,6 +24452,12 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
cert->keyType = ED25519_KEY;
else if (ed448Key)
cert->keyType = ED448_KEY;
#ifdef HAVE_LIBOQS
else if ((falconKey != NULL) && (falconKey->level == 1))
cert->keyType = FALCON_LEVEL1_KEY;
else if ((falconKey != NULL) && (falconKey->level == 5))
cert->keyType = FALCON_LEVEL5_KEY;
#endif
else
return BAD_FUNC_ARG;
@ -24099,7 +24468,8 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
return MEMORY_E;
#endif
ret = EncodeCertReq(cert, der, rsaKey, dsaKey, eccKey, ed25519Key, ed448Key);
ret = EncodeCertReq(cert, der, rsaKey, dsaKey, eccKey, ed25519Key, ed448Key,
falconKey);
if (ret == 0) {
if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
@ -24147,6 +24517,12 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
else if (ed448Key != NULL) {
cert->keyType = ED448_KEY;
}
else if ((falconKey != NULL) && (falconKey->level == 1)) {
cert->keyType = FALCON_LEVEL1_KEY;
}
else if ((falconKey != NULL) && (falconKey->level == 5)) {
cert->keyType = FALCON_LEVEL5_KEY;
}
else {
ret = BAD_FUNC_ARG;
}
@ -24278,6 +24654,7 @@ int wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
ecc_key* eccKey = NULL;
ed25519_key* ed25519Key = NULL;
ed448_key* ed448Key = NULL;
falcon_key* falconKey = NULL;
if (keyType == RSA_TYPE)
rsaKey = (RsaKey*)key;
@ -24289,22 +24666,27 @@ int wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
ed25519Key = (ed25519_key*)key;
else if (keyType == ED448_TYPE)
ed448Key = (ed448_key*)key;
else if (keyType == FALCON_LEVEL1_TYPE)
falconKey = (falcon_key*)key;
else if (keyType == FALCON_LEVEL5_TYPE)
falconKey = (falcon_key*)key;
return MakeCertReq(cert, derBuffer, derSz, rsaKey, dsaKey, eccKey, ed25519Key,
ed448Key);
return MakeCertReq(cert, derBuffer, derSz, rsaKey, dsaKey, eccKey,
ed25519Key, ed448Key, falconKey);
}
int wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
RsaKey* rsaKey, ecc_key* eccKey)
{
return MakeCertReq(cert, derBuffer, derSz, rsaKey, NULL, eccKey, NULL, NULL);
return MakeCertReq(cert, derBuffer, derSz, rsaKey, NULL, eccKey, NULL,
NULL, NULL);
}
#endif /* WOLFSSL_CERT_REQ */
static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key,
ed448_key* ed448Key, WC_RNG* rng)
ed448_key* ed448Key, falcon_key* falconKey, WC_RNG* rng)
{
int sigSz = 0;
void* heap = NULL;
@ -24357,8 +24739,8 @@ static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
}
sigSz = MakeSignature(certSignCtx, buf, requestSz, certSignCtx->sig,
MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, ed448Key, rng, sType,
heap);
MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, ed448Key,
falconKey, rng, sType, heap);
#ifdef WOLFSSL_ASYNC_CRYPT
if (sigSz == WC_PENDING_E) {
/* Not free'ing certSignCtx->sig here because it could still be in use
@ -24384,10 +24766,11 @@ static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
int wc_SignCert_ex(int requestSz, int sType, byte* buf, word32 buffSz,
int keyType, void* key, WC_RNG* rng)
{
RsaKey* rsaKey = NULL;
ecc_key* eccKey = NULL;
ed25519_key* ed25519Key = NULL;
ed448_key* ed448Key = NULL;
RsaKey* rsaKey = NULL;
ecc_key* eccKey = NULL;
ed25519_key* ed25519Key = NULL;
ed448_key* ed448Key = NULL;
falcon_key* falconKey = NULL;
if (keyType == RSA_TYPE)
rsaKey = (RsaKey*)key;
@ -24397,16 +24780,21 @@ int wc_SignCert_ex(int requestSz, int sType, byte* buf, word32 buffSz,
ed25519Key = (ed25519_key*)key;
else if (keyType == ED448_TYPE)
ed448Key = (ed448_key*)key;
else if (keyType == FALCON_LEVEL1_TYPE)
falconKey = (falcon_key*)key;
else if (keyType == FALCON_LEVEL5_TYPE)
falconKey = (falcon_key*)key;
return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, ed25519Key,
ed448Key, rng);
ed448Key, falconKey, rng);
}
int wc_SignCert(int requestSz, int sType, byte* buf, word32 buffSz,
RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng)
{
return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, NULL, NULL,
rng);
NULL, rng);
}
int wc_MakeSelfCert(Cert* cert, byte* buf, word32 buffSz,
@ -24440,14 +24828,14 @@ int wc_GetSubjectRaw(byte **subjectRaw, Cert *cert)
/* Set KID from public key */
static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
ed25519_key* ed25519Key, ed448_key* ed448Key,
int kid_type)
falcon_key* falconKey, int kid_type)
{
byte *buf;
int bufferSz, ret;
if (cert == NULL ||
(rsakey == NULL && eckey == NULL && ed25519Key == NULL &&
ed448Key == NULL) ||
ed448Key == NULL && falconKey == NULL) ||
(kid_type != SKID_TYPE && kid_type != AKID_TYPE))
return BAD_FUNC_ARG;
@ -24480,6 +24868,12 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
bufferSz = wc_Ed448PublicKeyToDer(ed448Key, buf, MAX_PUBLIC_KEY_SZ, 0);
}
#endif
#if defined(HAVE_LIBOQS)
if (falconKey != NULL) {
bufferSz = wc_Falcon_PublicKeyToDer(falconKey, buf, MAX_PUBLIC_KEY_SZ,
0);
}
#endif
if (bufferSz <= 0) {
XFREE(buf, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
@ -24504,10 +24898,11 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
{
RsaKey* rsaKey = NULL;
ecc_key* eccKey = NULL;
ed25519_key* ed25519Key = NULL;
ed448_key* ed448Key = NULL;
RsaKey* rsaKey = NULL;
ecc_key* eccKey = NULL;
ed25519_key* ed25519Key = NULL;
ed448_key* ed448Key = NULL;
falcon_key* falconKey = NULL;
if (keyType == RSA_TYPE)
rsaKey = (RsaKey*)key;
@ -24517,23 +24912,29 @@ int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
ed25519Key = (ed25519_key*)key;
else if (keyType == ED448_TYPE)
ed448Key = (ed448_key*)key;
else if (keyType == FALCON_LEVEL1_TYPE)
falconKey = (falcon_key*)key;
else if (keyType == FALCON_LEVEL5_TYPE)
falconKey = (falcon_key*)key;
return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, ed25519Key, ed448Key,
SKID_TYPE);
falconKey, SKID_TYPE);
}
/* Set SKID from RSA or ECC public key */
int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
{
return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, NULL, SKID_TYPE);
return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, NULL, NULL,
SKID_TYPE);
}
int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
{
RsaKey* rsaKey = NULL;
ecc_key* eccKey = NULL;
ed25519_key* ed25519Key = NULL;
ed448_key* ed448Key = NULL;
RsaKey* rsaKey = NULL;
ecc_key* eccKey = NULL;
ed25519_key* ed25519Key = NULL;
ed448_key* ed448Key = NULL;
falcon_key* falconKey = NULL;
if (keyType == RSA_TYPE)
rsaKey = (RsaKey*)key;
@ -24543,15 +24944,18 @@ int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
ed25519Key = (ed25519_key*)key;
else if (keyType == ED448_TYPE)
ed448Key = (ed448_key*)key;
else if (keyType == FALCON_LEVEL1_TYPE)
falconKey = (falcon_key*)key;
return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, ed25519Key, ed448Key,
AKID_TYPE);
falconKey, AKID_TYPE);
}
/* Set SKID from RSA or ECC public key */
int wc_SetAuthKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
{
return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, NULL, AKID_TYPE);
return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, NULL, NULL,
AKID_TYPE);
}
@ -27698,6 +28102,76 @@ int wc_Ed448PublicKeyDecode(const byte* input, word32* inOutIdx,
}
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
#if defined(HAVE_LIBOQS)
int wc_Falcon_PrivateKeyDecode(const byte* input, word32* inOutIdx,
falcon_key* key, word32 inSz)
{
int ret = 0;
byte privKey[FALCON_MAX_KEY_SIZE], pubKey[FALCON_MAX_PUB_KEY_SIZE];
word32 privKeyLen = (word32)sizeof(privKey);
word32 pubKeyLen = (word32)sizeof(pubKey);
int keytype = 0;
if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
return BAD_FUNC_ARG;
}
if (key->level == 1) {
keytype = FALCON_LEVEL1k;
}
else if (key->level == 5) {
keytype = FALCON_LEVEL5k;
}
else {
return BAD_FUNC_ARG;
}
ret = DecodeAsymKey(input, inOutIdx, inSz, privKey, &privKeyLen,
pubKey, &pubKeyLen, keytype);
if (ret == 0) {
if (pubKeyLen == 0) {
ret = wc_falcon_import_private_only(privKey, privKeyLen,
key);
}
else {
ret = wc_falcon_import_private_key(privKey, privKeyLen,
pubKey, pubKeyLen, key);
}
}
return ret;
}
int wc_Falcon_PublicKeyDecode(const byte* input, word32* inOutIdx,
falcon_key* key, word32 inSz)
{
int ret = 0;
byte pubKey[FALCON_MAX_PUB_KEY_SIZE];
word32 pubKeyLen = (word32)sizeof(pubKey);
int keytype = 0;
if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) {
return BAD_FUNC_ARG;
}
if (key->level == 1) {
keytype = FALCON_LEVEL1k;
}
else if (key->level == 5) {
keytype = FALCON_LEVEL5k;
}
else {
return BAD_FUNC_ARG;
}
ret = DecodeAsymKeyPublic(input, inOutIdx, inSz, pubKey, &pubKeyLen,
keytype);
if (ret == 0) {
ret = wc_falcon_import_public(pubKey, pubKeyLen, key);
}
return ret;
}
#endif /* HAVE_LIBOQS */
#if defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)
int wc_Curve448PrivateKeyDecode(const byte* input, word32* inOutIdx,
curve448_key* key, word32 inSz)
@ -27763,6 +28237,47 @@ int wc_Ed448PrivateKeyToDer(ed448_key* key, byte* output, word32 inLen)
#endif /* HAVE_ED448 && HAVE_ED448_KEY_EXPORT */
#if defined(HAVE_LIBOQS)
int wc_Falcon_KeyToDer(falcon_key* key, byte* output, word32 inLen)
{
if (key == NULL) {
return BAD_FUNC_ARG;
}
if (key->level == 1) {
return SetAsymKeyDer(key->k, FALCON_LEVEL1_KEY_SIZE, key->p,
FALCON_LEVEL1_KEY_SIZE, output, inLen,
FALCON_LEVEL1k);
}
else if (key->level == 5) {
return SetAsymKeyDer(key->k, FALCON_LEVEL5_KEY_SIZE, key->p,
FALCON_LEVEL5_KEY_SIZE, output, inLen,
FALCON_LEVEL5k);
}
return BAD_FUNC_ARG;
}
int wc_Falcon_PrivateKeyToDer(falcon_key* key, byte* output, word32 inLen)
{
if (key == NULL) {
return BAD_FUNC_ARG;
}
if (key->level == 1) {
return SetAsymKeyDer(key->k, FALCON_LEVEL1_KEY_SIZE, NULL, 0, output,
inLen, FALCON_LEVEL1k);
}
else if (key->level == 5) {
return SetAsymKeyDer(key->k, FALCON_LEVEL5_KEY_SIZE, NULL, 0, output,
inLen, FALCON_LEVEL5k);
}
return BAD_FUNC_ARG;
}
#endif /* HAVE_LIBOQS */
#if defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_EXPORT)
/* Write private Curve448 key to DER format,
* length on success else < 0 */

View File

@ -0,0 +1,678 @@
/* falcon.c
*
* Copyright (C) 2006-2021 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* 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-1335, USA
*/
/* Based on ed448.c and Reworked for Falcon by Anthony Hu. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/* in case user set HAVE_LIBOQS there */
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/asn.h>
#ifdef HAVE_LIBOQS
#include <oqs/oqs.h>
#include <wolfssl/wolfcrypt/falcon.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#endif
/* Sign the message using the falcon private key.
*
* in [in] Message to sign.
* inLen [in] Length of the message in bytes.
* out [in] Buffer to write signature into.
* outLen [in/out] On in, size of buffer.
* On out, the length of the signature in bytes.
* key [in] Falcon key to use when signing
* returns BAD_FUNC_ARG when a parameter is NULL or public key not set,
* BUFFER_E when outLen is less than FALCON_LEVEL1_SIG_SIZE,
* 0 otherwise.
*/
int wc_falcon_sign_msg(const byte* in, word32 inLen,
byte* out, word32 *outLen,
falcon_key* key)
{
int ret = 0;
OQS_SIG *oqssig = NULL;
/* sanity check on arguments */
if ((in == NULL) || (out == NULL) || (outLen == NULL) || (key == NULL)) {
ret = BAD_FUNC_ARG;
}
if ((ret == 0) && (!key->prvKeySet)) {
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
if (key->level == 1) {
oqssig = OQS_SIG_new(OQS_SIG_alg_falcon_512);
}
else if (key->level == 5) {
oqssig = OQS_SIG_new(OQS_SIG_alg_falcon_1024);
}
if (oqssig == NULL) {
ret = SIG_TYPE_E;
}
}
/* check and set up out length */
if (ret == 0) {
if ((key->level == 1) && (*outLen < FALCON_LEVEL1_SIG_SIZE)) {
*outLen = FALCON_LEVEL1_SIG_SIZE;
ret = BUFFER_E;
}
else if ((key->level == 5) && (*outLen < FALCON_LEVEL5_SIG_SIZE)) {
*outLen = FALCON_LEVEL5_SIG_SIZE;
ret = BUFFER_E;
}
}
if ((ret == 0) &&
(OQS_SIG_sign(oqssig, out, (size_t *)outLen, in, inLen, key->k)
== OQS_ERROR)) {
ret = BAD_FUNC_ARG;
}
if (oqssig != NULL) {
OQS_SIG_free(oqssig);
}
return ret;
}
/* Verify the message using the falcon public key.
*
* sig [in] Signature to verify.
* sigLen [in] Size of signature in bytes.
* msg [in] Message to verify.
* msgLen [in] Length of the message in bytes.
* res [out] *res is set to 1 on successful verification.
* key [in] Falcon key to use to verify.
* returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
* BUFFER_E when sigLen is less than FALCON_LEVEL1_SIG_SIZE,
* 0 otherwise.
*/
int wc_falcon_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* res, falcon_key* key)
{
int ret = 0;
OQS_SIG *oqssig = NULL;
if (key == NULL || sig == NULL || msg == NULL || res == NULL) {
ret = BAD_FUNC_ARG;
}
if ((ret == 0) && (!key->pubKeySet)) {
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
if (key->level == 1) {
oqssig = OQS_SIG_new(OQS_SIG_alg_falcon_512);
}
else if (key->level == 5) {
oqssig = OQS_SIG_new(OQS_SIG_alg_falcon_1024);
}
if (oqssig == NULL) {
ret = SIG_TYPE_E;
}
}
if ((ret == 0) &&
(OQS_SIG_verify(oqssig, msg, msgLen, sig, sigLen, key->p)
== OQS_ERROR)) {
ret = SIG_VERIFY_E;
}
if (ret == 0) {
*res = 1;
}
if (oqssig != NULL) {
OQS_SIG_free(oqssig);
}
return ret;
}
/* Initialize the falcon private/public key.
*
* key [in] Falcon key.
* returns BAD_FUNC_ARG when key is NULL
*/
int wc_falcon_init(falcon_key* key)
{
if (key == NULL) {
return BAD_FUNC_ARG;
}
ForceZero(key, sizeof(key));
return 0;
}
/* Set the level of the falcon private/public key.
*
* key [out] Falcon key.
* level [in] Either 1 or 5.
* returns BAD_FUNC_ARG when key is NULL or level is not 1 and not 5.
*/
int wc_falcon_set_level(falcon_key* key, byte level)
{
if (key == NULL) {
return BAD_FUNC_ARG;
}
if (level != 1 && level != 5) {
return BAD_FUNC_ARG;
}
key->level = level;
key->pubKeySet = 0;
key->prvKeySet = 0;
return 0;
}
/* Get the level of the falcon private/public key.
*
* key [in] Falcon key.
* level [out] The level.
* returns BAD_FUNC_ARG when key is NULL or level has not been set.
*/
int wc_falcon_get_level(falcon_key* key, byte* level)
{
if (key == NULL || level == NULL) {
return BAD_FUNC_ARG;
}
if (key->level != 1 && key->level != 5) {
return BAD_FUNC_ARG;
}
*level = key->level;
return 0;
}
/* Clears the falcon key data
*
* key [in] Falcon key.
*/
void wc_falcon_free(falcon_key* key)
{
if (key != NULL) {
ForceZero(key, sizeof(key));
}
}
/* Export the falcon public key.
*
* key [in] Falcon public key.
* out [in] Array to hold public key.
* outLen [in/out] On in, the number of bytes in array.
* On out, the number bytes put into array.
* returns BAD_FUNC_ARG when a parameter is NULL,
* ECC_BAD_ARG_E when outLen is less than FALCON_LEVEL1_PUB_KEY_SIZE,
* 0 otherwise.
*/
int wc_falcon_export_public(falcon_key* key,
byte* out, word32* outLen)
{
/* sanity check on arguments */
if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
return BAD_FUNC_ARG;
}
if ((key->level != 1) && (key->level != 5)) {
return BAD_FUNC_ARG;
}
if (!key->pubKeySet) {
return BAD_FUNC_ARG;
}
/* check and set up out length */
if ((key->level == 1) && (*outLen < FALCON_LEVEL1_PUB_KEY_SIZE)) {
*outLen = FALCON_LEVEL1_PUB_KEY_SIZE;
return BUFFER_E;
}
else if ((key->level == 5) && (*outLen < FALCON_LEVEL5_PUB_KEY_SIZE)) {
*outLen = FALCON_LEVEL5_PUB_KEY_SIZE;
return BUFFER_E;
}
if (key->level == 1) {
*outLen = FALCON_LEVEL1_PUB_KEY_SIZE;
XMEMCPY(out, key->p, FALCON_LEVEL1_PUB_KEY_SIZE);
}
else if (key->level == 5) {
*outLen = FALCON_LEVEL5_PUB_KEY_SIZE;
XMEMCPY(out, key->p, FALCON_LEVEL5_PUB_KEY_SIZE);
}
return 0;
}
/* Import a falcon public key from a byte array.
* Public key encoded in big-endian.
*
* in [in] Array holding public key.
* inLen [in] Number of bytes of data in array.
* key [in] Falcon public key.
* returns BAD_FUNC_ARG when a parameter is NULL or key format is not supported,
* 0 otherwise.
*/
int wc_falcon_import_public(const byte* in, word32 inLen,
falcon_key* key)
{
/* sanity check on arguments */
if ((in == NULL) || (key == NULL)) {
return BAD_FUNC_ARG;
}
if ((key->level != 1) && (key->level != 5)) {
return BAD_FUNC_ARG;
}
if ((key->level == 1) && (inLen != FALCON_LEVEL1_PUB_KEY_SIZE)) {
return BAD_FUNC_ARG;
}
else if ((key->level == 5) && (inLen != FALCON_LEVEL5_PUB_KEY_SIZE)) {
return BAD_FUNC_ARG;
}
XMEMCPY(key->p, in, inLen);
key->pubKeySet = 1;
return 0;
}
static int parse_private_key(const byte* priv, word32 privSz,
byte** out, word32 *outSz,
falcon_key* key) {
word32 idx = 0;
int ret = 0;
int length = 0;
/* sanity check on arguments */
if ((priv == NULL) || (key == NULL)) {
return BAD_FUNC_ARG;
}
if ((key->level != 1) && (key->level != 5)) {
return BAD_FUNC_ARG;
}
/* At this point, it is still a PKCS8 private key. */
if ((ret = ToTraditionalInline(priv, &idx, privSz)) < 0) {
return ret;
}
/* Now it is a octet_string(concat(priv,pub)) */
if ((ret = GetOctetString(priv, &idx, &length, privSz)) < 0) {
return ret;
}
*out = (byte *)priv + idx;
*outSz = privSz - idx;
/* And finally it is concat(priv,pub). Key size check. */
if ((key->level == 1) && (*outSz != FALCON_LEVEL1_KEY_SIZE +
FALCON_LEVEL1_PUB_KEY_SIZE)) {
return BAD_FUNC_ARG;
}
else if ((key->level == 5) && (*outSz != FALCON_LEVEL5_KEY_SIZE +
FALCON_LEVEL5_PUB_KEY_SIZE)) {
return BAD_FUNC_ARG;
}
return 0;
}
/* Import a falcon private key from a byte array.
*
* priv [in] Array holding private key.
* privSz [in] Number of bytes of data in array.
* key [in] Falcon private key.
* returns BAD_FUNC_ARG when a parameter is NULL or privSz is less than
* FALCON_LEVEL1_KEY_SIZE,
* 0 otherwise.
*/
int wc_falcon_import_private_only(const byte* priv, word32 privSz,
falcon_key* key)
{
int ret = 0;
byte *newPriv = NULL;
word32 newPrivSz = 0;
if ((ret = parse_private_key(priv, privSz, &newPriv, &newPrivSz, key))
!= 0) {
return ret;
}
if (key->level == 1) {
XMEMCPY(key->k, newPriv, FALCON_LEVEL1_KEY_SIZE);
}
else if (key->level == 5) {
XMEMCPY(key->k, newPriv, FALCON_LEVEL5_KEY_SIZE);
}
key->prvKeySet = 1;
return 0;
}
/* Import a falcon private and public keys from byte array(s).
*
* priv [in] Array holding private key or private+public keys
* privSz [in] Number of bytes of data in private key array.
* pub [in] Array holding public key (or NULL).
* pubSz [in] Number of bytes of data in public key array (or 0).
* key [in] Falcon private/public key.
* returns BAD_FUNC_ARG when a required parameter is NULL or an invalid
* combination of keys/lengths is supplied, 0 otherwise.
*/
int wc_falcon_import_private_key(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz,
falcon_key* key)
{
int ret = 0;
byte *newPriv = NULL;
word32 newPrivSz = 0;
if ((ret = parse_private_key(priv, privSz, &newPriv, &newPrivSz, key))
!= 0) {
return ret;
}
if (pub == NULL) {
if (pubSz != 0) {
return BAD_FUNC_ARG;
}
if ((newPrivSz != FALCON_LEVEL1_PRV_KEY_SIZE) &&
(newPrivSz != FALCON_LEVEL5_PRV_KEY_SIZE)) {
return BAD_FUNC_ARG;
}
if (key->level == 1) {
pub = newPriv + FALCON_LEVEL1_KEY_SIZE;
pubSz = FALCON_LEVEL1_PUB_KEY_SIZE;
}
else if (key->level == 5) {
pub = newPriv + FALCON_LEVEL5_KEY_SIZE;
pubSz = FALCON_LEVEL5_PUB_KEY_SIZE;
}
}
else if ((pubSz != FALCON_LEVEL1_PUB_KEY_SIZE) &&
(pubSz != FALCON_LEVEL5_PUB_KEY_SIZE)) {
return BAD_FUNC_ARG;
}
/* import public key */
ret = wc_falcon_import_public(pub, pubSz, key);
if (ret == 0) {
/* make the private key (priv + pub) */
if (key->level == 1) {
XMEMCPY(key->k, newPriv, FALCON_LEVEL1_KEY_SIZE);
}
else if (key->level == 5) {
XMEMCPY(key->k, newPriv, FALCON_LEVEL5_KEY_SIZE);
}
key->prvKeySet = 1;
}
return ret;
}
/* Export the falcon private key.
*
* key [in] Falcon private key.
* out [in] Array to hold private key.
* outLen [in/out] On in, the number of bytes in array.
* On out, the number bytes put into array.
* returns BAD_FUNC_ARG when a parameter is NULL,
* ECC_BAD_ARG_E when outLen is less than FALCON_LEVEL1_KEY_SIZE,
* 0 otherwise.
*/
int wc_falcon_export_private_only(falcon_key* key, byte* out, word32* outLen)
{
/* sanity checks on arguments */
if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
return BAD_FUNC_ARG;
}
if ((key->level != 1) && (key->level != 5)) {
return BAD_FUNC_ARG;
}
/* check and set up out length */
if ((key->level == 1) && (*outLen < FALCON_LEVEL1_KEY_SIZE)) {
*outLen = FALCON_LEVEL1_KEY_SIZE;
return BUFFER_E;
}
else if ((key->level == 5) && (*outLen < FALCON_LEVEL5_KEY_SIZE)) {
*outLen = FALCON_LEVEL5_KEY_SIZE;
return BUFFER_E;
}
if (key->level == 1) {
*outLen = FALCON_LEVEL1_KEY_SIZE;
}
else if (key->level == 5) {
*outLen = FALCON_LEVEL5_KEY_SIZE;
}
XMEMCPY(out, key->k, *outLen);
return 0;
}
/* Export the falcon private and public key.
*
* key [in] Falcon private/public key.
* out [in] Array to hold private and public key.
* outLen [in/out] On in, the number of bytes in array.
* On out, the number bytes put into array.
* returns BAD_FUNC_ARG when a parameter is NULL,
* BUFFER_E when outLen is less than FALCON_LEVEL1_PRV_KEY_SIZE,
* 0 otherwise.
*/
int wc_falcon_export_private(falcon_key* key, byte* out, word32* outLen)
{
/* sanity checks on arguments */
if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
return BAD_FUNC_ARG;
}
if ((key->level != 1) && (key->level != 5)) {
return BAD_FUNC_ARG;
}
if ((key->level == 1) && (*outLen < FALCON_LEVEL1_PRV_KEY_SIZE)) {
*outLen = FALCON_LEVEL1_PRV_KEY_SIZE;
return BUFFER_E;
}
else if ((key->level == 5) && (*outLen < FALCON_LEVEL5_PRV_KEY_SIZE)) {
*outLen = FALCON_LEVEL5_PRV_KEY_SIZE;
return BUFFER_E;
}
if (key->level == 1) {
*outLen = FALCON_LEVEL1_PRV_KEY_SIZE;
XMEMCPY(out, key->k, FALCON_LEVEL1_PRV_KEY_SIZE);
XMEMCPY(out + FALCON_LEVEL1_PRV_KEY_SIZE, key->p,
FALCON_LEVEL1_PUB_KEY_SIZE);
}
else if (key->level == 5) {
*outLen = FALCON_LEVEL5_PRV_KEY_SIZE;
XMEMCPY(out, key->k, FALCON_LEVEL5_PRV_KEY_SIZE);
XMEMCPY(out + FALCON_LEVEL5_PRV_KEY_SIZE, key->p,
FALCON_LEVEL5_PUB_KEY_SIZE);
}
return 0;
}
/* Export the falcon private and public key.
*
* key [in] Falcon private/public key.
* priv [in] Array to hold private key.
* privSz [in/out] On in, the number of bytes in private key array.
* pub [in] Array to hold public key.
* pubSz [in/out] On in, the number of bytes in public key array.
* On out, the number bytes put into array.
* returns BAD_FUNC_ARG when a parameter is NULL,
* BUFFER_E when privSz is less than FALCON_LEVEL1_PRV_KEY_SIZE or pubSz is less
* than FALCON_LEVEL1_PUB_KEY_SIZE,
* 0 otherwise.
*/
int wc_falcon_export_key(falcon_key* key, byte* priv, word32 *privSz,
byte* pub, word32 *pubSz)
{
int ret = 0;
/* export private part */
ret = wc_falcon_export_private(key, priv, privSz);
if (ret == 0) {
/* export public part */
ret = wc_falcon_export_public(key, pub, pubSz);
}
return ret;
}
/* Check the public key of the falcon key matches the private key.
*
* key [in] Falcon private/public key.
* returns BAD_FUNC_ARG when key is NULL,
* PUBLIC_KEY_E when the public key is not set or doesn't match,
* other -ve value on hash failure,
* 0 otherwise.
*/
int wc_falcon_check_key(falcon_key* key)
{
/* Might want to try to sign and verify a random message here. */
int ret = 0;
(void)key;
return ret;
}
/* Returns the size of a falcon private key.
*
* key [in] Falcon private/public key.
* returns BAD_FUNC_ARG when key is NULL,
* FALCON_LEVEL1_KEY_SIZE otherwise.
*/
int wc_falcon_size(falcon_key* key)
{
if (key == NULL) {
return BAD_FUNC_ARG;
}
if (key->level == 1) {
return FALCON_LEVEL1_KEY_SIZE;
}
else if (key->level == 5) {
return FALCON_LEVEL5_KEY_SIZE;
}
return BAD_FUNC_ARG;
}
/* Returns the size of a falcon private plus public key.
*
* key [in] Falcon private/public key.
* returns BAD_FUNC_ARG when key is NULL,
* FALCON_LEVEL1_PRV_KEY_SIZE otherwise.
*/
int wc_falcon_priv_size(falcon_key* key)
{
if (key == NULL) {
return BAD_FUNC_ARG;
}
if (key->level == 1) {
return FALCON_LEVEL1_PRV_KEY_SIZE;
}
else if (key->level == 5) {
return FALCON_LEVEL5_PRV_KEY_SIZE;
}
return BAD_FUNC_ARG;
}
/* Returns the size of a falcon public key.
*
* key [in] Falcon private/public key.
* returns BAD_FUNC_ARG when key is NULL,
* FALCON_LEVEL1_PUB_KEY_SIZE otherwise.
*/
int wc_falcon_pub_size(falcon_key* key)
{
if (key == NULL) {
return BAD_FUNC_ARG;
}
if (key->level == 1) {
return FALCON_LEVEL1_PUB_KEY_SIZE;
}
else if (key->level == 5) {
return FALCON_LEVEL5_PUB_KEY_SIZE;
}
return BAD_FUNC_ARG;
}
/* Returns the size of a falcon signature.
*
* key [in] Falcon private/public key.
* returns BAD_FUNC_ARG when key is NULL,
* FALCON_LEVEL1_SIG_SIZE otherwise.
*/
int wc_falcon_sig_size(falcon_key* key)
{
if (key == NULL) {
return BAD_FUNC_ARG;
}
if (key->level == 1) {
return FALCON_LEVEL1_SIG_SIZE;
}
else if (key->level == 5) {
return FALCON_LEVEL5_SIG_SIZE;
}
return BAD_FUNC_ARG;
}
#endif /* HAVE_LIBOQS */

View File

@ -175,6 +175,7 @@ enum wolfSSL_ErrorCodes {
HTTP_VERSION_ERR = -448, /* HTTP Version error */
HTTP_APPSTR_ERR = -449, /* HTTP Application string error */
UNSUPPORTED_PROTO_VERSION = -450, /* bad/unsupported protocol version*/
FALCON_KEY_SIZE_E = -451, /* Wrong key size for Falcon. */
/* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */

View File

@ -116,6 +116,9 @@
#ifdef HAVE_CURVE448
#include <wolfssl/wolfcrypt/curve448.h>
#endif
#ifdef HAVE_LIBOQS
#include <wolfssl/wolfcrypt/falcon.h>
#endif
#ifndef WOLFSSL_NO_DEF_TICKET_ENC_CB
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && \
!defined(WOLFSSL_TICKET_ENC_AES128_GCM) && \
@ -1239,9 +1242,13 @@ enum Misc {
#else
#ifndef NO_PSK
ENCRYPT_LEN = 512 + MAX_PSK_ID_LEN + 2, /* 4096 bit static buffer */
#else
#ifdef HAVE_LIBOQS
ENCRYPT_LEN = 5000, /* allow 40000 bit static buffer for falcon */
#else
ENCRYPT_LEN = 512, /* allow 4096 bit static buffer */
#endif
#endif
#endif
SIZEOF_SENDER = 4, /* clnt or srvr */
FINISHED_SZ = 36, /* WC_MD5_DIGEST_SIZE + WC_SHA_DIGEST_SIZE */
@ -1448,10 +1455,21 @@ enum Misc {
ED448_SA_MAJOR = 8, /* Most significant byte for ED448 */
ED448_SA_MINOR = 8, /* Least significant byte for ED448 */
OQS_SA_MAJOR = 0xFE,/* Most significant byte used with OQS sig algos
*/
/* These match what OQS has defined in their OpenSSL fork. */
FALCON_LEVEL1_SA_MAJOR = 0xFE,
FALCON_LEVEL1_SA_MINOR = 0x0B,
FALCON_LEVEL5_SA_MAJOR = 0xFE,
FALCON_LEVEL5_SA_MINOR = 0x0E,
MIN_RSA_SHA512_PSS_BITS = 512 * 2 + 8 * 8, /* Min key size */
MIN_RSA_SHA384_PSS_BITS = 384 * 2 + 8 * 8, /* Min key size */
#ifndef NO_RSA
#if defined(HAVE_LIBOQS)
MAX_CERT_VERIFY_SZ = 20000, /* For Falcon */
#elif !defined(NO_RSA)
MAX_CERT_VERIFY_SZ = WOLFSSL_MAX_RSA_BITS / 8, /* max RSA bytes */
#elif defined(HAVE_ECC)
MAX_CERT_VERIFY_SZ = ECC_MAX_SIG_SIZE, /* max ECC */
@ -1479,7 +1497,9 @@ enum Misc {
MAX_WOLFSSL_FILE_SIZE = 1024ul * 1024ul * 4, /* 4 mb file size alloc limit */
#endif
#ifdef WOLFSSL_HAPROXY
#if defined(HAVE_LIBOQS)
MAX_X509_SIZE = 5120, /* max static x509 buffer size; falcon is big */
#elif defined(WOLFSSL_HAPROXY)
MAX_X509_SIZE = 3072, /* max static x509 buffer size */
#else
MAX_X509_SIZE = 2048, /* max static x509 buffer size */
@ -1526,7 +1546,7 @@ enum Misc {
/* number of items in the signature algo list */
#ifndef WOLFSSL_MAX_SIGALGO
#define WOLFSSL_MAX_SIGALGO 36
#define WOLFSSL_MAX_SIGALGO 38
#endif
@ -1548,6 +1568,13 @@ enum Misc {
#endif
#define MIN_ECCKEY_SZ (WOLFSSL_MIN_ECC_BITS / 8)
#ifdef HAVE_LIBOQS
/* set minimum Falcon key size allowed */
#ifndef MIN_FALCONKEY_SZ
#define MIN_FALCONKEY_SZ 897
#endif
#endif
/* set minimum RSA key size allowed */
#ifndef WOLFSSL_MIN_RSA_BITS
#ifdef WOLFSSL_MAX_STRENGTH
@ -1877,10 +1904,14 @@ struct Suites {
WOLFSSL_LOCAL void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig,
int haveRSAsig, int haveAnon,
int tls1_2, int keySz);
WOLFSSL_LOCAL void InitSuites(Suites*, ProtocolVersion, int, word16, word16,
word16, word16, word16, word16, word16, int);
int haveRSAsig, int haveFalconSig,
int haveAnon, int tls1_2, int keySz);
WOLFSSL_LOCAL void InitSuites(Suites* suites, ProtocolVersion pv, int keySz,
word16 haveRSA, word16 havePSK, word16 haveDH,
word16 haveECDSAsig, word16 haveECC,
word16 haveStaticECC, word16 haveFalconSig,
word16 haveAnon, int side);
WOLFSSL_LOCAL int MatchSuite(WOLFSSL* ssl, Suites* peerSuites);
WOLFSSL_LOCAL int SetCipherList(WOLFSSL_CTX*, Suites*, const char* list);
WOLFSSL_LOCAL int SetSuitesHashSigAlgo(Suites*, const char* list);
@ -2088,6 +2119,10 @@ struct WOLFSSL_CERT_MANAGER {
wolfSSL_Mutex refMutex; /* reference count mutex */
#endif
int refCount; /* reference count */
#ifdef HAVE_LIBOQS
short minFalconKeySz; /* minimum allowed Falcon key size */
#endif
};
WOLFSSL_LOCAL int CM_SaveCertCache(WOLFSSL_CERT_MANAGER*, const char*);
@ -2772,6 +2807,7 @@ struct WOLFSSL_CTX {
byte haveECC:1; /* ECC available */
byte haveDH:1; /* server DH parms set by user */
byte haveECDSAsig:1; /* server cert signed w/ ECDSA */
byte haveFalconSig:1; /* server cert signed w/ Falcon */
byte haveStaticECC:1; /* static server ECC private key */
byte partialWrite:1; /* only one msg per write call */
byte quietShutdown:1; /* don't send close notify */
@ -2830,6 +2866,9 @@ struct WOLFSSL_CTX {
#endif
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
short minEccKeySz; /* minimum ECC key size */
#endif
#ifdef HAVE_LIBOQS
short minFalconKeySz; /* minimum Falcon key size */
#endif
unsigned long mask; /* store SSL_OP_ flags */
#ifdef OPENSSL_EXTRA
@ -3102,14 +3141,16 @@ enum KeyExchangeAlgorithm {
/* Supported Authentication Schemes */
enum SignatureAlgorithm {
anonymous_sa_algo = 0,
rsa_sa_algo = 1,
dsa_sa_algo = 2,
ecc_dsa_sa_algo = 3,
rsa_pss_sa_algo = 8,
ed25519_sa_algo = 9,
rsa_pss_pss_algo = 10,
ed448_sa_algo = 11
anonymous_sa_algo = 0,
rsa_sa_algo = 1,
dsa_sa_algo = 2,
ecc_dsa_sa_algo = 3,
rsa_pss_sa_algo = 8,
ed25519_sa_algo = 9,
rsa_pss_pss_algo = 10,
ed448_sa_algo = 11,
falcon_level1_sa_algo = 12,
falcon_level5_sa_algo = 13
};
#define PSS_RSAE_TO_PSS_PSS(macAlgo) \
@ -3142,7 +3183,8 @@ enum ClientCertificateType {
fortezza_kea_cert = 20,
ecdsa_sign = 64,
rsa_fixed_ecdh = 65,
ecdsa_fixed_ecdh = 66
ecdsa_fixed_ecdh = 66,
falcon_sign = 67,
};
@ -3561,6 +3603,7 @@ typedef struct Options {
word16 haveDH:1; /* server DH parms set by user */
word16 haveECDSAsig:1; /* server ECDSA signed cert */
word16 haveStaticECC:1; /* static server ECC private key */
word16 haveFalconSig:1; /* server Falcon signed cert */
word16 havePeerCert:1; /* do we have peer's cert */
word16 havePeerVerify:1; /* and peer's cert verify */
word16 usingPSK_cipher:1; /* are using psk as cipher */
@ -3667,6 +3710,9 @@ typedef struct Options {
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
short minEccKeySz; /* minimum ECC key size */
#endif
#if defined(HAVE_LIBOQS)
short minFalconKeySz; /* minimum Falcon key size */
#endif
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
byte verifyDepth; /* maximum verification depth */
#endif
@ -3831,9 +3877,10 @@ struct WOLFSSL_X509 {
buffer pubKey;
int pubKeyOID;
DNS_entry* altNamesNext; /* hint for retrieval */
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
defined(HAVE_LIBOQS)
word32 pkCurveOID;
#endif /* HAVE_ECC */
#endif /* HAVE_ECC || HAVE_LIBOQS */
#ifndef NO_CERTS
DerBuffer* derCert; /* may need */
#endif
@ -4241,6 +4288,10 @@ struct WOLFSSL {
curve448_key* peerX448Key;
byte peerX448KeyPresent;
#endif
#ifdef HAVE_LIBOQS
falcon_key* peerFalconKey;
byte peerFalconKeyPresent;
#endif
#ifdef HAVE_LIBZ
z_stream c_stream; /* compression stream */
z_stream d_stream; /* decompression stream */

View File

@ -999,14 +999,16 @@ enum Block_Sum {
enum Key_Sum {
DSAk = 515,
RSAk = 645,
ECDSAk = 518,
ED25519k = 256, /* 1.3.101.112 */
X25519k = 254, /* 1.3.101.110 */
ED448k = 257, /* 1.3.101.113 */
X448k = 255, /* 1.3.101.111 */
DHk = 647, /* dhKeyAgreement OID: 1.2.840.113549.1.3.1 */
DSAk = 515,
RSAk = 645,
ECDSAk = 518,
ED25519k = 256, /* 1.3.101.112 */
X25519k = 254, /* 1.3.101.110 */
ED448k = 257, /* 1.3.101.113 */
X448k = 255, /* 1.3.101.111 */
DHk = 647, /* dhKeyAgreement OID: 1.2.840.113549.1.3.1 */
FALCON_LEVEL1k = 268, /* 1.3.9999.3.1 */
FALCON_LEVEL5k = 271 /* 1.3.9999.3.4 */
};
#if !defined(NO_AES) || defined(HAVE_PKCS7)
@ -1240,6 +1242,9 @@ struct SignatureCtx {
#endif
#ifdef HAVE_ED448
struct ed448_key* ed448;
#endif
#ifdef HAVE_LIBOQS
struct falcon_key* falcon;
#endif
void* ptr;
} key;
@ -1936,18 +1941,20 @@ WOLFSSL_LOCAL int wc_MIME_free_hdrs(MimeHdr* head);
enum cert_enums {
#ifdef WOLFSSL_CERT_EXT
NAME_ENTRIES = 12,
NAME_ENTRIES = 12,
#else
NAME_ENTRIES = 11,
NAME_ENTRIES = 11,
#endif
JOINT_LEN = 2,
EMAIL_JOINT_LEN = 9,
PILOT_JOINT_LEN = 10,
RSA_KEY = 10,
ECC_KEY = 12,
ED25519_KEY = 13,
ED448_KEY = 14,
DSA_KEY = 15
JOINT_LEN = 2,
EMAIL_JOINT_LEN = 9,
PILOT_JOINT_LEN = 10,
RSA_KEY = 10,
ECC_KEY = 12,
ED25519_KEY = 13,
ED448_KEY = 14,
DSA_KEY = 15,
FALCON_LEVEL1_KEY = 16,
FALCON_LEVEL5_KEY = 17
};
#endif /* WOLFSSL_CERT_GEN */

View File

@ -75,6 +75,10 @@ This library defines the interface APIs for X509 certificates.
typedef struct DhKey DhKey;
#define WC_DH_TYPE_DEFINED
#endif
#ifndef WC_FALCONKEY_TYPE_DEFINED
typedef struct falcon_key falcon_key;
#define WC_FALCONKEY_TYPE_DEFINED
#endif
enum Ecc_Sum {
ECC_SECP112R1_OID = 182,
@ -138,6 +142,8 @@ enum CertType {
DETECT_CERT_TYPE,
DH_PRIVATEKEY_TYPE,
X942_PARAM_TYPE,
FALCON_LEVEL1_TYPE,
FALCON_LEVEL5_TYPE,
};
@ -169,7 +175,10 @@ enum Ctc_SigType {
CTC_SHA3_512wRSA = 430,
CTC_ED25519 = 256,
CTC_ED448 = 257
CTC_ED448 = 257,
CTC_FALCON_LEVEL1 = 268,
CTC_FALCON_LEVEL5 = 271
};
enum Ctc_Encoding {
@ -609,7 +618,8 @@ WOLFSSL_API int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz);
((defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)) || \
(defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_EXPORT)) || \
(defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)) || \
(defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_EXPORT)))
(defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_EXPORT)) || \
(defined(HAVE_LIBOQS)))
#define WC_ENABLE_ASYM_KEY_EXPORT
#endif
@ -617,7 +627,8 @@ WOLFSSL_API int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz);
((defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)) || \
(defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_IMPORT)) || \
(defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)) || \
(defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)))
(defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)) || \
(defined(HAVE_LIBOQS)))
#define WC_ENABLE_ASYM_KEY_IMPORT
#endif
@ -656,6 +667,14 @@ WOLFSSL_API int wc_Ed448PublicKeyToDer(ed448_key*, byte*, word32, int);
#endif
#endif /* HAVE_ED448 */
#ifdef HAVE_LIBOQS
WOLFSSL_API int wc_Falcon_PrivateKeyDecode(const byte*, word32*, falcon_key*, word32);
WOLFSSL_API int wc_Falcon_PublicKeyDecode(const byte*, word32*, falcon_key*, word32);
WOLFSSL_API int wc_Falcon_KeyToDer(falcon_key*, byte*, word32);
WOLFSSL_API int wc_Falcon_PrivateKeyToDer(falcon_key*, byte*, word32);
WOLFSSL_API int wc_Falcon_PublicKeyToDer(falcon_key*, byte*, word32, int);
#endif /* HAVE_LIBOQS */
#ifdef HAVE_CURVE448
#ifdef HAVE_CURVE448_KEY_IMPORT
WOLFSSL_API int wc_Curve448PrivateKeyDecode(const byte*, word32*, curve448_key*, word32);

View File

@ -0,0 +1,129 @@
/* falcon.h
*
* Copyright (C) 2021 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* 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-1335, USA
*/
/*!
\file wolfssl/wolfcrypt/falcon.h
*/
/* Interfaces for Falcon NIST Level 1 (Falcon512) and Falcon NIST Level 5
* (Falcon1024). */
#ifndef WOLF_CRYPT_FALCON_H
#define WOLF_CRYPT_FALCON_H
#include <wolfssl/wolfcrypt/types.h>
#ifdef HAVE_LIBOQS
#include <oqs/oqs.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Macros Definitions */
#define FALCON_LEVEL1_KEY_SIZE OQS_SIG_falcon_512_length_secret_key
#define FALCON_LEVEL1_SIG_SIZE OQS_SIG_falcon_512_length_signature
#define FALCON_LEVEL1_PUB_KEY_SIZE OQS_SIG_falcon_512_length_public_key
#define FALCON_LEVEL1_PRV_KEY_SIZE (FALCON_LEVEL1_PUB_KEY_SIZE+FALCON_LEVEL1_KEY_SIZE)
#define FALCON_LEVEL5_KEY_SIZE OQS_SIG_falcon_1024_length_secret_key
#define FALCON_LEVEL5_SIG_SIZE OQS_SIG_falcon_1024_length_signature
#define FALCON_LEVEL5_PUB_KEY_SIZE OQS_SIG_falcon_1024_length_public_key
#define FALCON_LEVEL5_PRV_KEY_SIZE (FALCON_LEVEL5_PUB_KEY_SIZE+FALCON_LEVEL5_KEY_SIZE)
#define FALCON_MAX_KEY_SIZE FALCON_LEVEL5_KEY_SIZE
#define FALCON_MAX_SIG_SIZE FALCON_LEVEL5_SIG_SIZE
#define FALCON_MAX_PUB_KEY_SIZE FALCON_LEVEL5_PUB_KEY_SIZE
#define FALCON_MAX_PRV_KEY_SIZE FALCON_LEVEL5_PRV_KEY_SIZE
/* Structs */
struct falcon_key {
bool pubKeySet;
bool prvKeySet;
byte level;
byte p[FALCON_MAX_PUB_KEY_SIZE];
byte k[FALCON_MAX_PRV_KEY_SIZE];
};
#ifndef WC_FALCONKEY_TYPE_DEFINED
typedef struct falcon_key falcon_key;
#define WC_FALCONKEY_TYPE_DEFINED
#endif
/* Functions */
WOLFSSL_API
int wc_falcon_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen,
falcon_key* key);
WOLFSSL_API
int wc_falcon_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* res, falcon_key* key);
WOLFSSL_API
int wc_falcon_init(falcon_key* key);
WOLFSSL_API
int wc_falcon_set_level(falcon_key* key, byte level);
WOLFSSL_API
int wc_falcon_get_level(falcon_key* key, byte* level);
WOLFSSL_API
void wc_falcon_free(falcon_key* key);
WOLFSSL_API
int wc_falcon_import_public(const byte* in, word32 inLen, falcon_key* key);
WOLFSSL_API
int wc_falcon_import_private_only(const byte* priv, word32 privSz,
falcon_key* key);
WOLFSSL_API
int wc_falcon_import_private_key(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz,
falcon_key* key);
WOLFSSL_API
int wc_falcon_export_public(falcon_key*, byte* out, word32* outLen);
WOLFSSL_API
int wc_falcon_export_private_only(falcon_key* key, byte* out, word32* outLen);
WOLFSSL_API
int wc_falcon_export_private(falcon_key* key, byte* out, word32* outLen);
WOLFSSL_API
int wc_falcon_export_key(falcon_key* key, byte* priv, word32 *privSz,
byte* pub, word32 *pubSz);
WOLFSSL_API
int wc_falcon_check_key(falcon_key* key);
WOLFSSL_API
int wc_falcon_size(falcon_key* key);
WOLFSSL_API
int wc_falcon_priv_size(falcon_key* key);
WOLFSSL_API
int wc_falcon_pub_size(falcon_key* key);
WOLFSSL_API
int wc_falcon_sig_size(falcon_key* key);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HAVE_LIBOQS */
#endif /* WOLF_CRYPT_FALCON_H */

View File

@ -21,6 +21,7 @@ nobase_include_HEADERS+= \
wolfssl/wolfcrypt/ge_operations.h \
wolfssl/wolfcrypt/curve448.h \
wolfssl/wolfcrypt/ed448.h \
wolfssl/wolfcrypt/falcon.h \
wolfssl/wolfcrypt/fe_448.h \
wolfssl/wolfcrypt/ge_448.h \
wolfssl/wolfcrypt/eccsi.h \

View File

@ -838,6 +838,7 @@ decouple library dependencies with standard string, memory and so on.
DYNAMIC_TYPE_ED448 = 92,
DYNAMIC_TYPE_AES = 93,
DYNAMIC_TYPE_CMAC = 94,
DYNAMIC_TYPE_FALCON = 95,
DYNAMIC_TYPE_SNIFFER_SERVER = 1000,
DYNAMIC_TYPE_SNIFFER_SESSION = 1001,
DYNAMIC_TYPE_SNIFFER_PB = 1002,