mirror of https://github.com/wolfSSL/wolfssl.git
The NIST round 3 Falcon Signature Scheme integration.
parent
2745f394e5
commit
81def76b18
72
INSTALL
72
INSTALL
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
296
src/internal.c
296
src/internal.c
|
@ -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
182
src/ssl.c
|
@ -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
|
||||
};
|
||||
|
|
129
src/tls13.c
129
src/tls13.c
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
|
@ -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 !!!!! */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
|
@ -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 \
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue