1 /* falcon.c
2  *
3  * Copyright (C) 2006-2021 wolfSSL Inc.
4  *
5  * This file is part of wolfSSL.
6  *
7  * wolfSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * wolfSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20  */
21 
22 /* Based on ed448.c and Reworked for Falcon by Anthony Hu. */
23 
24 #ifdef HAVE_CONFIG_H
25     #include <config.h>
26 #endif
27 
28 /* in case user set HAVE_PQC there */
29 #include <wolfssl/wolfcrypt/settings.h>
30 
31 #include <wolfssl/wolfcrypt/asn.h>
32 
33 #ifdef HAVE_PQC
34 
35 #ifdef HAVE_LIBOQS
36 #include <oqs/oqs.h>
37 #endif
38 
39 #include <wolfssl/wolfcrypt/falcon.h>
40 #include <wolfssl/wolfcrypt/error-crypt.h>
41 #ifdef NO_INLINE
42     #include <wolfssl/wolfcrypt/misc.h>
43 #else
44     #define WOLFSSL_MISC_INCLUDED
45     #include <wolfcrypt/src/misc.c>
46 #endif
47 
48 /* Sign the message using the falcon private key.
49  *
50  *  in          [in]      Message to sign.
51  *  inLen       [in]      Length of the message in bytes.
52  *  out         [in]      Buffer to write signature into.
53  *  outLen      [in/out]  On in, size of buffer.
54  *                        On out, the length of the signature in bytes.
55  *  key         [in]      Falcon key to use when signing
56  *  returns BAD_FUNC_ARG when a parameter is NULL or public key not set,
57  *          BUFFER_E when outLen is less than FALCON_LEVEL1_SIG_SIZE,
58  *          0 otherwise.
59  */
wc_falcon_sign_msg(const byte * in,word32 inLen,byte * out,word32 * outLen,falcon_key * key)60 int wc_falcon_sign_msg(const byte* in, word32 inLen,
61                               byte* out, word32 *outLen,
62                               falcon_key* key)
63 {
64     int ret = 0;
65 #ifdef HAVE_LIBOQS
66     OQS_SIG *oqssig = NULL;
67     size_t localOutLen = 0;
68 
69     /* sanity check on arguments */
70     if ((in == NULL) || (out == NULL) || (outLen == NULL) || (key == NULL)) {
71         ret = BAD_FUNC_ARG;
72     }
73 
74     if ((ret == 0) && (!key->prvKeySet)) {
75         ret = BAD_FUNC_ARG;
76     }
77 
78     if (ret == 0) {
79         if (key->level == 1) {
80             oqssig = OQS_SIG_new(OQS_SIG_alg_falcon_512);
81         }
82         else if (key->level == 5) {
83             oqssig = OQS_SIG_new(OQS_SIG_alg_falcon_1024);
84         }
85 
86         if (oqssig == NULL) {
87             ret = SIG_TYPE_E;
88         }
89     }
90 
91     /* check and set up out length */
92     if (ret == 0) {
93         if ((key->level == 1) && (*outLen < FALCON_LEVEL1_SIG_SIZE)) {
94             *outLen = FALCON_LEVEL1_SIG_SIZE;
95             ret = BUFFER_E;
96         }
97         else if ((key->level == 5) && (*outLen < FALCON_LEVEL5_SIG_SIZE)) {
98             *outLen = FALCON_LEVEL5_SIG_SIZE;
99             ret = BUFFER_E;
100         }
101         localOutLen = *outLen;
102     }
103 
104     if ((ret == 0) &&
105         (OQS_SIG_sign(oqssig, out, &localOutLen, in, inLen, key->k)
106          == OQS_ERROR)) {
107         ret = BAD_FUNC_ARG;
108     }
109 
110     if (ret == 0) {
111         *outLen = (word32)localOutLen;
112     }
113 
114     if (oqssig != NULL) {
115         OQS_SIG_free(oqssig);
116     }
117 #endif
118     return ret;
119 }
120 
121 /* Verify the message using the falcon public key.
122  *
123  *  sig         [in]  Signature to verify.
124  *  sigLen      [in]  Size of signature in bytes.
125  *  msg         [in]  Message to verify.
126  *  msgLen      [in]  Length of the message in bytes.
127  *  res         [out] *res is set to 1 on successful verification.
128  *  key         [in]  Falcon key to use to verify.
129  *  returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
130  *          BUFFER_E when sigLen is less than FALCON_LEVEL1_SIG_SIZE,
131  *          0 otherwise.
132  */
wc_falcon_verify_msg(const byte * sig,word32 sigLen,const byte * msg,word32 msgLen,int * res,falcon_key * key)133 int wc_falcon_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
134                         word32 msgLen, int* res, falcon_key* key)
135 {
136     int ret = 0;
137 #ifdef HAVE_LIBOQS
138     OQS_SIG *oqssig = NULL;
139 
140     if (key == NULL || sig == NULL || msg == NULL || res == NULL) {
141         ret = BAD_FUNC_ARG;
142     }
143 
144     if ((ret == 0) && (!key->pubKeySet)) {
145         ret = BAD_FUNC_ARG;
146     }
147 
148     if (ret == 0) {
149         if (key->level == 1) {
150             oqssig = OQS_SIG_new(OQS_SIG_alg_falcon_512);
151         }
152         else if (key->level == 5) {
153             oqssig = OQS_SIG_new(OQS_SIG_alg_falcon_1024);
154         }
155 
156         if (oqssig == NULL) {
157             ret = SIG_TYPE_E;
158         }
159     }
160 
161     if ((ret == 0) &&
162         (OQS_SIG_verify(oqssig, msg, msgLen, sig, sigLen, key->p)
163          == OQS_ERROR)) {
164          ret = SIG_VERIFY_E;
165     }
166 
167     if (ret == 0) {
168         *res = 1;
169     }
170 
171     if (oqssig != NULL) {
172         OQS_SIG_free(oqssig);
173     }
174 #endif
175 
176     return ret;
177 }
178 
179 /* Initialize the falcon private/public key.
180  *
181  * key  [in]  Falcon key.
182  * returns BAD_FUNC_ARG when key is NULL
183  */
wc_falcon_init(falcon_key * key)184 int wc_falcon_init(falcon_key* key)
185 {
186     if (key == NULL) {
187         return BAD_FUNC_ARG;
188     }
189 
190     ForceZero(key, sizeof(key));
191     return 0;
192 }
193 
194 /* Set the level of the falcon private/public key.
195  *
196  * key   [out]  Falcon key.
197  * level [in]   Either 1 or 5.
198  * returns BAD_FUNC_ARG when key is NULL or level is not 1 and not 5.
199  */
wc_falcon_set_level(falcon_key * key,byte level)200 int wc_falcon_set_level(falcon_key* key, byte level)
201 {
202     if (key == NULL) {
203         return BAD_FUNC_ARG;
204     }
205 
206     if (level != 1 && level != 5) {
207         return BAD_FUNC_ARG;
208     }
209 
210     key->level = level;
211     key->pubKeySet = 0;
212     key->prvKeySet = 0;
213     return 0;
214 }
215 
216 /* Get the level of the falcon private/public key.
217  *
218  * key   [in]  Falcon key.
219  * level [out] The level.
220  * returns BAD_FUNC_ARG when key is NULL or level has not been set.
221  */
wc_falcon_get_level(falcon_key * key,byte * level)222 int wc_falcon_get_level(falcon_key* key, byte* level)
223 {
224     if (key == NULL || level == NULL) {
225         return BAD_FUNC_ARG;
226     }
227 
228     if (key->level != 1 && key->level != 5) {
229         return BAD_FUNC_ARG;
230     }
231 
232     *level = key->level;
233     return 0;
234 }
235 
236 /* Clears the falcon key data
237  *
238  * key  [in]  Falcon key.
239  */
wc_falcon_free(falcon_key * key)240 void wc_falcon_free(falcon_key* key)
241 {
242     if (key != NULL) {
243         ForceZero(key, sizeof(key));
244     }
245 }
246 
247 /* Export the falcon public key.
248  *
249  * key     [in]      Falcon public key.
250  * out     [in]      Array to hold public key.
251  * outLen  [in/out]  On in, the number of bytes in array.
252  *                   On out, the number bytes put into array.
253  * returns BAD_FUNC_ARG when a parameter is NULL,
254  *         ECC_BAD_ARG_E when outLen is less than FALCON_LEVEL1_PUB_KEY_SIZE,
255  *         0 otherwise.
256  */
wc_falcon_export_public(falcon_key * key,byte * out,word32 * outLen)257 int wc_falcon_export_public(falcon_key* key,
258                             byte* out, word32* outLen)
259 {
260     /* sanity check on arguments */
261     if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
262         return BAD_FUNC_ARG;
263     }
264 
265     if ((key->level != 1) && (key->level != 5)) {
266         return BAD_FUNC_ARG;
267     }
268 
269     if (!key->pubKeySet) {
270         return BAD_FUNC_ARG;
271     }
272 
273     /* check and set up out length */
274     if ((key->level == 1) && (*outLen < FALCON_LEVEL1_PUB_KEY_SIZE)) {
275         *outLen = FALCON_LEVEL1_PUB_KEY_SIZE;
276         return BUFFER_E;
277     }
278     else if ((key->level == 5) && (*outLen < FALCON_LEVEL5_PUB_KEY_SIZE)) {
279         *outLen = FALCON_LEVEL5_PUB_KEY_SIZE;
280         return BUFFER_E;
281     }
282 
283     if (key->level == 1) {
284         *outLen = FALCON_LEVEL1_PUB_KEY_SIZE;
285         XMEMCPY(out, key->p, FALCON_LEVEL1_PUB_KEY_SIZE);
286     }
287     else if (key->level == 5) {
288         *outLen = FALCON_LEVEL5_PUB_KEY_SIZE;
289         XMEMCPY(out, key->p, FALCON_LEVEL5_PUB_KEY_SIZE);
290     }
291 
292     return 0;
293 }
294 
295 /* Import a falcon public key from a byte array.
296  * Public key encoded in big-endian.
297  *
298  * in      [in]  Array holding public key.
299  * inLen   [in]  Number of bytes of data in array.
300  * key     [in]  Falcon public key.
301  * returns BAD_FUNC_ARG when a parameter is NULL or key format is not supported,
302  *         0 otherwise.
303  */
wc_falcon_import_public(const byte * in,word32 inLen,falcon_key * key)304 int wc_falcon_import_public(const byte* in, word32 inLen,
305                                    falcon_key* key)
306 {
307     /* sanity check on arguments */
308     if ((in == NULL) || (key == NULL)) {
309         return BAD_FUNC_ARG;
310     }
311 
312     if ((key->level != 1) && (key->level != 5)) {
313         return BAD_FUNC_ARG;
314     }
315 
316     if ((key->level == 1) && (inLen != FALCON_LEVEL1_PUB_KEY_SIZE)) {
317         return BAD_FUNC_ARG;
318     }
319     else if ((key->level == 5) && (inLen != FALCON_LEVEL5_PUB_KEY_SIZE)) {
320         return BAD_FUNC_ARG;
321     }
322 
323     XMEMCPY(key->p, in, inLen);
324     key->pubKeySet = 1;
325 
326     return 0;
327 }
328 
parse_private_key(const byte * priv,word32 privSz,byte ** out,word32 * outSz,falcon_key * key)329 static int parse_private_key(const byte* priv, word32 privSz,
330                              byte** out, word32 *outSz,
331                              falcon_key* key) {
332     word32 idx = 0;
333     int ret = 0;
334     int length = 0;
335 
336     /* sanity check on arguments */
337     if ((priv == NULL) || (key == NULL)) {
338         return BAD_FUNC_ARG;
339     }
340 
341     if ((key->level != 1) && (key->level != 5)) {
342         return BAD_FUNC_ARG;
343     }
344 
345     /* At this point, it is still a PKCS8 private key. */
346     if ((ret = ToTraditionalInline(priv, &idx, privSz)) < 0) {
347         return ret;
348     }
349 
350     /* Now it is a octet_string(concat(priv,pub)) */
351     if ((ret = GetOctetString(priv, &idx, &length, privSz)) < 0) {
352         return ret;
353     }
354 
355     *out = (byte *)priv + idx;
356     *outSz = privSz - idx;
357 
358     /* And finally it is concat(priv,pub). Key size check. */
359     if ((key->level == 1) && (*outSz != FALCON_LEVEL1_KEY_SIZE +
360                                        FALCON_LEVEL1_PUB_KEY_SIZE)) {
361         return BAD_FUNC_ARG;
362     }
363     else if ((key->level == 5) && (*outSz != FALCON_LEVEL5_KEY_SIZE +
364                                             FALCON_LEVEL5_PUB_KEY_SIZE)) {
365         return BAD_FUNC_ARG;
366     }
367 
368     return 0;
369 }
370 
371 /* Import a falcon private key from a byte array.
372  *
373  * priv    [in]  Array holding private key.
374  * privSz  [in]  Number of bytes of data in array.
375  * key     [in]  Falcon private key.
376  * returns BAD_FUNC_ARG when a parameter is NULL or privSz is less than
377  *         FALCON_LEVEL1_KEY_SIZE,
378  *         0 otherwise.
379  */
wc_falcon_import_private_only(const byte * priv,word32 privSz,falcon_key * key)380 int wc_falcon_import_private_only(const byte* priv, word32 privSz,
381                                  falcon_key* key)
382 {
383     int ret = 0;
384     byte *newPriv = NULL;
385     word32 newPrivSz = 0;
386 
387     if ((ret = parse_private_key(priv, privSz, &newPriv, &newPrivSz, key))
388         != 0) {
389          return ret;
390     }
391 
392     if (key->level == 1) {
393         XMEMCPY(key->k, newPriv, FALCON_LEVEL1_KEY_SIZE);
394     }
395     else if (key->level == 5) {
396         XMEMCPY(key->k, newPriv, FALCON_LEVEL5_KEY_SIZE);
397     }
398     key->prvKeySet = 1;
399 
400     return 0;
401 }
402 
403 /* Import a falcon private and public keys from byte array(s).
404  *
405  * priv    [in]  Array holding private key or private+public keys
406  * privSz  [in]  Number of bytes of data in private key array.
407  * pub     [in]  Array holding public key (or NULL).
408  * pubSz   [in]  Number of bytes of data in public key array (or 0).
409  * key     [in]  Falcon private/public key.
410  * returns BAD_FUNC_ARG when a required parameter is NULL or an invalid
411  *         combination of keys/lengths is supplied, 0 otherwise.
412  */
wc_falcon_import_private_key(const byte * priv,word32 privSz,const byte * pub,word32 pubSz,falcon_key * key)413 int wc_falcon_import_private_key(const byte* priv, word32 privSz,
414                                         const byte* pub, word32 pubSz,
415                                         falcon_key* key)
416 {
417     int ret = 0;
418     byte *newPriv = NULL;
419     word32 newPrivSz = 0;
420 
421     if ((ret = parse_private_key(priv, privSz, &newPriv, &newPrivSz, key))
422         != 0) {
423          return ret;
424     }
425 
426     if (pub == NULL) {
427         if (pubSz != 0) {
428             return BAD_FUNC_ARG;
429         }
430 
431         if ((newPrivSz != FALCON_LEVEL1_PRV_KEY_SIZE) &&
432             (newPrivSz != FALCON_LEVEL5_PRV_KEY_SIZE)) {
433             return BAD_FUNC_ARG;
434         }
435 
436         if (key->level == 1) {
437             pub = newPriv + FALCON_LEVEL1_KEY_SIZE;
438             pubSz = FALCON_LEVEL1_PUB_KEY_SIZE;
439         }
440         else if (key->level == 5) {
441             pub = newPriv + FALCON_LEVEL5_KEY_SIZE;
442             pubSz = FALCON_LEVEL5_PUB_KEY_SIZE;
443         }
444     }
445     else if ((pubSz != FALCON_LEVEL1_PUB_KEY_SIZE) &&
446              (pubSz != FALCON_LEVEL5_PUB_KEY_SIZE)) {
447         return BAD_FUNC_ARG;
448     }
449 
450     /* import public key */
451     ret = wc_falcon_import_public(pub, pubSz, key);
452 
453     if (ret == 0) {
454         /* make the private key (priv + pub) */
455         if (key->level == 1) {
456             XMEMCPY(key->k, newPriv, FALCON_LEVEL1_KEY_SIZE);
457         }
458         else if (key->level == 5) {
459             XMEMCPY(key->k, newPriv, FALCON_LEVEL5_KEY_SIZE);
460         }
461         key->prvKeySet = 1;
462     }
463 
464     return ret;
465 }
466 
467 /* Export the falcon private key.
468  *
469  * key     [in]      Falcon private key.
470  * out     [in]      Array to hold private key.
471  * outLen  [in/out]  On in, the number of bytes in array.
472  *                   On out, the number bytes put into array.
473  * returns BAD_FUNC_ARG when a parameter is NULL,
474  *         ECC_BAD_ARG_E when outLen is less than FALCON_LEVEL1_KEY_SIZE,
475  *         0 otherwise.
476  */
wc_falcon_export_private_only(falcon_key * key,byte * out,word32 * outLen)477 int wc_falcon_export_private_only(falcon_key* key, byte* out, word32* outLen)
478 {
479     /* sanity checks on arguments */
480     if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
481         return BAD_FUNC_ARG;
482     }
483 
484     if ((key->level != 1) && (key->level != 5)) {
485         return BAD_FUNC_ARG;
486     }
487 
488     /* check and set up out length */
489     if ((key->level == 1) && (*outLen < FALCON_LEVEL1_KEY_SIZE)) {
490         *outLen = FALCON_LEVEL1_KEY_SIZE;
491         return BUFFER_E;
492     }
493     else if ((key->level == 5) && (*outLen < FALCON_LEVEL5_KEY_SIZE)) {
494         *outLen = FALCON_LEVEL5_KEY_SIZE;
495         return BUFFER_E;
496     }
497 
498     if (key->level == 1) {
499         *outLen = FALCON_LEVEL1_KEY_SIZE;
500     }
501     else if (key->level == 5) {
502         *outLen = FALCON_LEVEL5_KEY_SIZE;
503     }
504 
505     XMEMCPY(out, key->k, *outLen);
506 
507     return 0;
508 }
509 
510 /* Export the falcon private and public key.
511  *
512  * key     [in]      Falcon private/public key.
513  * out     [in]      Array to hold private and public key.
514  * outLen  [in/out]  On in, the number of bytes in array.
515  *                   On out, the number bytes put into array.
516  * returns BAD_FUNC_ARG when a parameter is NULL,
517  *         BUFFER_E when outLen is less than FALCON_LEVEL1_PRV_KEY_SIZE,
518  *         0 otherwise.
519  */
wc_falcon_export_private(falcon_key * key,byte * out,word32 * outLen)520 int wc_falcon_export_private(falcon_key* key, byte* out, word32* outLen)
521 {
522     /* sanity checks on arguments */
523     if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
524         return BAD_FUNC_ARG;
525     }
526 
527     if ((key->level != 1) && (key->level != 5)) {
528         return BAD_FUNC_ARG;
529     }
530 
531     if ((key->level == 1) && (*outLen < FALCON_LEVEL1_PRV_KEY_SIZE)) {
532         *outLen = FALCON_LEVEL1_PRV_KEY_SIZE;
533         return BUFFER_E;
534     }
535     else if ((key->level == 5) && (*outLen < FALCON_LEVEL5_PRV_KEY_SIZE)) {
536         *outLen = FALCON_LEVEL5_PRV_KEY_SIZE;
537         return BUFFER_E;
538     }
539 
540 
541     if (key->level == 1) {
542         *outLen = FALCON_LEVEL1_PRV_KEY_SIZE;
543         XMEMCPY(out, key->k, FALCON_LEVEL1_PRV_KEY_SIZE);
544         XMEMCPY(out + FALCON_LEVEL1_PRV_KEY_SIZE, key->p,
545                 FALCON_LEVEL1_PUB_KEY_SIZE);
546     }
547     else if (key->level == 5) {
548         *outLen = FALCON_LEVEL5_PRV_KEY_SIZE;
549         XMEMCPY(out, key->k, FALCON_LEVEL5_PRV_KEY_SIZE);
550         XMEMCPY(out + FALCON_LEVEL5_PRV_KEY_SIZE, key->p,
551                 FALCON_LEVEL5_PUB_KEY_SIZE);
552     }
553 
554     return 0;
555 }
556 
557 /* Export the falcon private and public key.
558  *
559  * key     [in]      Falcon private/public key.
560  * priv    [in]      Array to hold private key.
561  * privSz  [in/out]  On in, the number of bytes in private key array.
562  * pub     [in]      Array to hold  public key.
563  * pubSz   [in/out]  On in, the number of bytes in public key array.
564  *                   On out, the number bytes put into array.
565  * returns BAD_FUNC_ARG when a parameter is NULL,
566  *         BUFFER_E when privSz is less than FALCON_LEVEL1_PRV_KEY_SIZE or pubSz is less
567  *         than FALCON_LEVEL1_PUB_KEY_SIZE,
568  *         0 otherwise.
569  */
wc_falcon_export_key(falcon_key * key,byte * priv,word32 * privSz,byte * pub,word32 * pubSz)570 int wc_falcon_export_key(falcon_key* key, byte* priv, word32 *privSz,
571                         byte* pub, word32 *pubSz)
572 {
573     int ret = 0;
574 
575     /* export private part */
576     ret = wc_falcon_export_private(key, priv, privSz);
577     if (ret == 0) {
578         /* export public part */
579         ret = wc_falcon_export_public(key, pub, pubSz);
580     }
581 
582     return ret;
583 }
584 
585 /* Check the public key of the falcon key matches the private key.
586  *
587  * key     [in]      Falcon private/public key.
588  * returns BAD_FUNC_ARG when key is NULL,
589  *         PUBLIC_KEY_E when the public key is not set or doesn't match,
590  *         other -ve value on hash failure,
591  *         0 otherwise.
592  */
wc_falcon_check_key(falcon_key * key)593 int wc_falcon_check_key(falcon_key* key)
594 {
595     if (key == NULL) {
596         return BAD_FUNC_ARG;
597     }
598 
599     /* Assume everything is fine. */
600     return 0;
601 }
602 
603 /* Returns the size of a falcon private key.
604  *
605  * key     [in]      Falcon private/public key.
606  * returns BAD_FUNC_ARG when key is NULL,
607  *         FALCON_LEVEL1_KEY_SIZE otherwise.
608  */
wc_falcon_size(falcon_key * key)609 int wc_falcon_size(falcon_key* key)
610 {
611     if (key == NULL) {
612         return BAD_FUNC_ARG;
613     }
614 
615     if (key->level == 1) {
616         return FALCON_LEVEL1_KEY_SIZE;
617     }
618     else if (key->level == 5) {
619         return FALCON_LEVEL5_KEY_SIZE;
620     }
621 
622     return BAD_FUNC_ARG;
623 }
624 
625 /* Returns the size of a falcon private plus public key.
626  *
627  * key     [in]      Falcon private/public key.
628  * returns BAD_FUNC_ARG when key is NULL,
629  *         FALCON_LEVEL1_PRV_KEY_SIZE otherwise.
630  */
wc_falcon_priv_size(falcon_key * key)631 int wc_falcon_priv_size(falcon_key* key)
632 {
633     if (key == NULL) {
634         return BAD_FUNC_ARG;
635     }
636 
637     if (key->level == 1) {
638         return FALCON_LEVEL1_PRV_KEY_SIZE;
639     }
640     else if (key->level == 5) {
641         return FALCON_LEVEL5_PRV_KEY_SIZE;
642     }
643 
644     return BAD_FUNC_ARG;
645 }
646 
647 /* Returns the size of a falcon public key.
648  *
649  * key     [in]      Falcon private/public key.
650  * returns BAD_FUNC_ARG when key is NULL,
651  *         FALCON_LEVEL1_PUB_KEY_SIZE otherwise.
652  */
wc_falcon_pub_size(falcon_key * key)653 int wc_falcon_pub_size(falcon_key* key)
654 {
655     if (key == NULL) {
656         return BAD_FUNC_ARG;
657     }
658 
659     if (key->level == 1) {
660         return FALCON_LEVEL1_PUB_KEY_SIZE;
661     }
662     else if (key->level == 5) {
663         return FALCON_LEVEL5_PUB_KEY_SIZE;
664     }
665 
666     return BAD_FUNC_ARG;
667 }
668 
669 /* Returns the size of a falcon signature.
670  *
671  * key     [in]      Falcon private/public key.
672  * returns BAD_FUNC_ARG when key is NULL,
673  *         FALCON_LEVEL1_SIG_SIZE otherwise.
674  */
wc_falcon_sig_size(falcon_key * key)675 int wc_falcon_sig_size(falcon_key* key)
676 {
677     if (key == NULL) {
678         return BAD_FUNC_ARG;
679     }
680 
681     if (key->level == 1) {
682         return FALCON_LEVEL1_SIG_SIZE;
683     }
684     else if (key->level == 5) {
685         return FALCON_LEVEL5_SIG_SIZE;
686     }
687 
688     return BAD_FUNC_ARG;
689 }
690 #endif /* HAVE_PQC */
691