wolf SSL / wolfSSL

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers dh.c Source File

dh.c

00001 /* dh.c
00002  *
00003  * Copyright (C) 2006-2020 wolfSSL Inc.
00004  *
00005  * This file is part of wolfSSL.
00006  *
00007  * wolfSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * wolfSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
00020  */
00021 
00022 
00023 #ifdef HAVE_CONFIG_H
00024     #include <config.h>
00025 #endif
00026 
00027 #include <wolfssl/wolfcrypt/settings.h>
00028 
00029 #ifndef NO_DH
00030 
00031 #if defined(HAVE_FIPS) && \
00032     defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
00033 
00034     /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
00035     #define FIPS_NO_WRAPPERS
00036 
00037     #ifdef USE_WINDOWS_API
00038         #pragma code_seg(".fipsA$m")
00039         #pragma const_seg(".fipsB$m")
00040     #endif
00041 #endif
00042 
00043 #include <wolfssl/wolfcrypt/dh.h >
00044 #include <wolfssl/wolfcrypt/error-crypt.h >
00045 #include <wolfssl/wolfcrypt/logging.h >
00046 
00047 #ifdef WOLFSSL_HAVE_SP_DH
00048 #include <wolfssl/wolfcrypt/sp.h>
00049 #endif
00050 
00051 #ifdef NO_INLINE
00052     #include <wolfssl/wolfcrypt/misc.h>
00053 #else
00054     #define WOLFSSL_MISC_INCLUDED
00055     #include <wolfcrypt/src/misc.c>
00056 #endif
00057 
00058 
00059 /*
00060 Possible DH enable options:
00061  * NO_RSA:              Overall control of DH                 default: on (not defined)
00062  * WOLFSSL_OLD_PRIME_CHECK: Disables the new prime number check. It does not
00063                         directly effect this file, but it does speed up DH
00064                         removing the testing. It is not recommended to
00065                         disable the prime checking.           default: off
00066 
00067 */
00068 
00069 
00070 #if !defined(USER_MATH_LIB) && !defined(WOLFSSL_DH_CONST)
00071     #include <math.h>
00072     #define XPOW(x,y) pow((x),(y))
00073     #define XLOG(x)   log((x))
00074 #else
00075     /* user's own math lib */
00076 #endif
00077 
00078 #ifdef HAVE_FFDHE_2048
00079 static const byte dh_ffdhe2048_p[] = {
00080     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00081     0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
00082     0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
00083     0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
00084     0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
00085     0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
00086     0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
00087     0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
00088     0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
00089     0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
00090     0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
00091     0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
00092     0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
00093     0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
00094     0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
00095     0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
00096     0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
00097     0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
00098     0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
00099     0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
00100     0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
00101     0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
00102     0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
00103     0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
00104     0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
00105     0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
00106     0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
00107     0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
00108     0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
00109     0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
00110     0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97,
00111     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
00112 };
00113 static const byte dh_ffdhe2048_g[] = { 0x02 };
00114 #ifdef HAVE_FFDHE_Q
00115 static const byte dh_ffdhe2048_q[] = {
00116     0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00117     0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
00118     0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
00119     0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
00120     0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
00121     0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
00122     0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
00123     0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
00124     0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
00125     0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
00126     0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
00127     0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
00128     0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
00129     0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
00130     0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
00131     0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
00132     0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
00133     0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
00134     0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
00135     0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
00136     0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
00137     0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
00138     0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
00139     0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
00140     0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
00141     0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
00142     0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
00143     0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
00144     0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
00145     0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
00146     0x44, 0x35, 0xA1, 0x1C, 0x30, 0x94, 0x2E, 0x4B,
00147     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
00148 };
00149 #endif /* HAVE_FFDHE_Q */
00150 
00151 const DhParams* wc_Dh_ffdhe2048_Get(void)
00152 {
00153     static const DhParams ffdhe2048 = {
00154         #ifdef HAVE_FFDHE_Q
00155             dh_ffdhe2048_q, sizeof(dh_ffdhe2048_q),
00156         #endif /* HAVE_FFDHE_Q */
00157         dh_ffdhe2048_p, sizeof(dh_ffdhe2048_p),
00158         dh_ffdhe2048_g, sizeof(dh_ffdhe2048_g)
00159     };
00160     return &ffdhe2048;
00161 }
00162 #endif
00163 
00164 #ifdef HAVE_FFDHE_3072
00165 static const byte dh_ffdhe3072_p[] = {
00166     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00167     0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
00168     0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
00169     0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
00170     0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
00171     0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
00172     0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
00173     0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
00174     0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
00175     0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
00176     0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
00177     0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
00178     0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
00179     0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
00180     0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
00181     0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
00182     0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
00183     0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
00184     0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
00185     0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
00186     0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
00187     0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
00188     0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
00189     0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
00190     0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
00191     0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
00192     0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
00193     0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
00194     0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
00195     0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
00196     0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,
00197     0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,
00198     0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,
00199     0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,
00200     0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,
00201     0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,
00202     0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,
00203     0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,
00204     0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,
00205     0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,
00206     0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,
00207     0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,
00208     0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,
00209     0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,
00210     0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,
00211     0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,
00212     0x25, 0xE4, 0x1D, 0x2B, 0x66, 0xC6, 0x2E, 0x37,
00213     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
00214 };
00215 static const byte dh_ffdhe3072_g[] = { 0x02 };
00216 #ifdef HAVE_FFDHE_Q
00217 static const byte dh_ffdhe3072_q[] = {
00218     0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00219     0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
00220     0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
00221     0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
00222     0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
00223     0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
00224     0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
00225     0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
00226     0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
00227     0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
00228     0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
00229     0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
00230     0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
00231     0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
00232     0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
00233     0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
00234     0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
00235     0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
00236     0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
00237     0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
00238     0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
00239     0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
00240     0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
00241     0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
00242     0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
00243     0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
00244     0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
00245     0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
00246     0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
00247     0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
00248     0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,
00249     0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,
00250     0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,
00251     0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,
00252     0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,
00253     0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,
00254     0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,
00255     0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,
00256     0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,
00257     0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,
00258     0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,
00259     0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,
00260     0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,
00261     0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,
00262     0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,
00263     0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,
00264     0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x63, 0x17, 0x1B,
00265     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
00266 };
00267 #endif /* HAVE_FFDHE_Q */
00268 
00269 const DhParams* wc_Dh_ffdhe3072_Get(void)
00270 {
00271     static const DhParams ffdhe3072 = {
00272         #ifdef HAVE_FFDHE_Q
00273             dh_ffdhe3072_q, sizeof(dh_ffdhe3072_q),
00274         #endif /* HAVE_FFDHE_Q */
00275         dh_ffdhe3072_p, sizeof(dh_ffdhe3072_p),
00276         dh_ffdhe3072_g, sizeof(dh_ffdhe3072_g)
00277     };
00278     return &ffdhe3072;
00279 }
00280 #endif
00281 
00282 #ifdef HAVE_FFDHE_4096
00283 static const byte dh_ffdhe4096_p[] = {
00284     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00285     0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
00286     0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
00287     0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
00288     0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
00289     0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
00290     0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
00291     0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
00292     0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
00293     0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
00294     0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
00295     0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
00296     0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
00297     0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
00298     0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
00299     0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
00300     0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
00301     0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
00302     0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
00303     0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
00304     0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
00305     0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
00306     0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
00307     0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
00308     0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
00309     0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
00310     0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
00311     0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
00312     0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
00313     0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
00314     0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,
00315     0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,
00316     0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,
00317     0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,
00318     0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,
00319     0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,
00320     0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,
00321     0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,
00322     0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,
00323     0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,
00324     0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,
00325     0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,
00326     0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,
00327     0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,
00328     0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,
00329     0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,
00330     0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1,
00331     0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB,
00332     0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6,
00333     0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18,
00334     0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04,
00335     0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A,
00336     0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A,
00337     0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32,
00338     0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4,
00339     0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38,
00340     0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A,
00341     0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C,
00342     0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC,
00343     0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF,
00344     0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B,
00345     0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1,
00346     0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x65, 0x5F, 0x6A,
00347     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
00348 };
00349 static const byte dh_ffdhe4096_g[] = { 0x02 };
00350 #ifdef HAVE_FFDHE_Q
00351 static const byte dh_ffdhe4096_q[] = {
00352     0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00353     0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
00354     0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
00355     0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
00356     0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
00357     0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
00358     0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
00359     0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
00360     0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
00361     0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
00362     0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
00363     0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
00364     0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
00365     0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
00366     0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
00367     0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
00368     0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
00369     0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
00370     0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
00371     0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
00372     0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
00373     0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
00374     0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
00375     0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
00376     0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
00377     0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
00378     0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
00379     0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
00380     0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
00381     0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
00382     0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,
00383     0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,
00384     0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,
00385     0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,
00386     0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,
00387     0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,
00388     0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,
00389     0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,
00390     0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,
00391     0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,
00392     0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,
00393     0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,
00394     0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,
00395     0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,
00396     0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,
00397     0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,
00398     0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78,
00399     0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D,
00400     0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB,
00401     0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C,
00402     0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02,
00403     0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D,
00404     0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5,
00405     0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19,
00406     0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62,
00407     0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C,
00408     0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD,
00409     0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E,
00410     0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66,
00411     0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7,
00412     0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35,
00413     0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70,
00414     0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x32, 0xAF, 0xB5,
00415     0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
00416 };
00417 #endif /* HAVE_FFDHE_Q */
00418 
00419 const DhParams* wc_Dh_ffdhe4096_Get(void)
00420 {
00421     static const DhParams ffdhe4096 = {
00422         #ifdef HAVE_FFDHE_Q
00423             dh_ffdhe4096_q, sizeof(dh_ffdhe4096_q),
00424         #endif /* HAVE_FFDHE_Q */
00425         dh_ffdhe4096_p, sizeof(dh_ffdhe4096_p),
00426         dh_ffdhe4096_g, sizeof(dh_ffdhe4096_g)
00427     };
00428     return &ffdhe4096;
00429 }
00430 #endif
00431 
00432 #ifdef HAVE_FFDHE_6144
00433 static const byte dh_ffdhe6144_p[] = {
00434     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00435     0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
00436     0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
00437     0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
00438     0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
00439     0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
00440     0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
00441     0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
00442     0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
00443     0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
00444     0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
00445     0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
00446     0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
00447     0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
00448     0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
00449     0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
00450     0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
00451     0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
00452     0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
00453     0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
00454     0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
00455     0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
00456     0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
00457     0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
00458     0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
00459     0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
00460     0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
00461     0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
00462     0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
00463     0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
00464     0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,
00465     0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,
00466     0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,
00467     0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,
00468     0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,
00469     0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,
00470     0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,
00471     0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,
00472     0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,
00473     0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,
00474     0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,
00475     0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,
00476     0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,
00477     0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,
00478     0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,
00479     0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,
00480     0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1,
00481     0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB,
00482     0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6,
00483     0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18,
00484     0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04,
00485     0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A,
00486     0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A,
00487     0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32,
00488     0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4,
00489     0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38,
00490     0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A,
00491     0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C,
00492     0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC,
00493     0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF,
00494     0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B,
00495     0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1,
00496     0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02,
00497     0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A,
00498     0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A,
00499     0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6,
00500     0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8,
00501     0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C,
00502     0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A,
00503     0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71,
00504     0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F,
00505     0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77,
00506     0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10,
00507     0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8,
00508     0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3,
00509     0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E,
00510     0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3,
00511     0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4,
00512     0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1,
00513     0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92,
00514     0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6,
00515     0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82,
00516     0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE,
00517     0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C,
00518     0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E,
00519     0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46,
00520     0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A,
00521     0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17,
00522     0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03,
00523     0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04,
00524     0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6,
00525     0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69,
00526     0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1,
00527     0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4,
00528     0xA4, 0x0E, 0x32, 0x9C, 0xD0, 0xE4, 0x0E, 0x65,
00529     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
00530 };
00531 static const byte dh_ffdhe6144_g[] = { 0x02 };
00532 #ifdef HAVE_FFDHE_Q
00533 static const byte dh_ffdhe6144_q[] = {
00534     0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00535     0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
00536     0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
00537     0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
00538     0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
00539     0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
00540     0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
00541     0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
00542     0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
00543     0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
00544     0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
00545     0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
00546     0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
00547     0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
00548     0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
00549     0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
00550     0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
00551     0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
00552     0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
00553     0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
00554     0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
00555     0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
00556     0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
00557     0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
00558     0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
00559     0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
00560     0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
00561     0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
00562     0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
00563     0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
00564     0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,
00565     0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,
00566     0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,
00567     0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,
00568     0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,
00569     0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,
00570     0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,
00571     0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,
00572     0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,
00573     0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,
00574     0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,
00575     0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,
00576     0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,
00577     0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,
00578     0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,
00579     0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,
00580     0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78,
00581     0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D,
00582     0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB,
00583     0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C,
00584     0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02,
00585     0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D,
00586     0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5,
00587     0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19,
00588     0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62,
00589     0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C,
00590     0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD,
00591     0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E,
00592     0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66,
00593     0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7,
00594     0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35,
00595     0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70,
00596     0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x06, 0xEC, 0x81,
00597     0x05, 0xFE, 0xB2, 0x5B, 0x22, 0x81, 0xB6, 0x3D,
00598     0x27, 0x33, 0xBE, 0x96, 0x1C, 0x29, 0x95, 0x1D,
00599     0x11, 0xDD, 0x22, 0x21, 0x65, 0x7A, 0x9F, 0x53,
00600     0x1D, 0xDA, 0x2A, 0x19, 0x4D, 0xBB, 0x12, 0x64,
00601     0x48, 0xBD, 0xEE, 0xB2, 0x58, 0xE0, 0x7E, 0xA6,
00602     0x59, 0xC7, 0x46, 0x19, 0xA6, 0x38, 0x0E, 0x1D,
00603     0x66, 0xD6, 0x83, 0x2B, 0xFE, 0x67, 0xF6, 0x38,
00604     0xCD, 0x8F, 0xAE, 0x1F, 0x27, 0x23, 0x02, 0x0F,
00605     0x9C, 0x40, 0xA3, 0xFD, 0xA6, 0x7E, 0xDA, 0x3B,
00606     0xD2, 0x92, 0x38, 0xFB, 0xD4, 0xD4, 0xB4, 0x88,
00607     0x5C, 0x2A, 0x99, 0x17, 0x6D, 0xB1, 0xA0, 0x6C,
00608     0x50, 0x07, 0x78, 0x49, 0x1A, 0x82, 0x88, 0xF1,
00609     0x85, 0x5F, 0x60, 0xFF, 0xFC, 0xF1, 0xD1, 0x37,
00610     0x3F, 0xD9, 0x4F, 0xC6, 0x0C, 0x18, 0x11, 0xE1,
00611     0xAC, 0x3F, 0x1C, 0x6D, 0x00, 0x3B, 0xEC, 0xDA,
00612     0x3B, 0x1F, 0x27, 0x25, 0xCA, 0x59, 0x5D, 0xE0,
00613     0xCA, 0x63, 0x32, 0x8F, 0x3B, 0xE5, 0x7C, 0xC9,
00614     0x77, 0x55, 0x60, 0x11, 0x95, 0x14, 0x0D, 0xFB,
00615     0x59, 0xD3, 0x9C, 0xE0, 0x91, 0x30, 0x8B, 0x41,
00616     0x05, 0x74, 0x6D, 0xAC, 0x23, 0xD3, 0x3E, 0x5F,
00617     0x7C, 0xE4, 0x84, 0x8D, 0xA3, 0x16, 0xA9, 0xC6,
00618     0x6B, 0x95, 0x81, 0xBA, 0x35, 0x73, 0xBF, 0xAF,
00619     0x31, 0x14, 0x96, 0x18, 0x8A, 0xB1, 0x54, 0x23,
00620     0x28, 0x2E, 0xE4, 0x16, 0xDC, 0x2A, 0x19, 0xC5,
00621     0x72, 0x4F, 0xA9, 0x1A, 0xE4, 0xAD, 0xC8, 0x8B,
00622     0xC6, 0x67, 0x96, 0xEA, 0xE5, 0x67, 0x7A, 0x01,
00623     0xF6, 0x4E, 0x8C, 0x08, 0x63, 0x13, 0x95, 0x82,
00624     0x2D, 0x9D, 0xB8, 0xFC, 0xEE, 0x35, 0xC0, 0x6B,
00625     0x1F, 0xEE, 0xA5, 0x47, 0x4D, 0x6D, 0x8F, 0x34,
00626     0xB1, 0x53, 0x4A, 0x93, 0x6A, 0x18, 0xB0, 0xE0,
00627     0xD2, 0x0E, 0xAB, 0x86, 0xBC, 0x9C, 0x6D, 0x6A,
00628     0x52, 0x07, 0x19, 0x4E, 0x68, 0x72, 0x07, 0x32,
00629     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
00630 };
00631 #endif /* HAVE_FFDHE_Q */
00632 
00633 const DhParams* wc_Dh_ffdhe6144_Get(void)
00634 {
00635     static const DhParams ffdhe6144 = {
00636         #ifdef HAVE_FFDHE_Q
00637             dh_ffdhe6144_q, sizeof(dh_ffdhe6144_q),
00638         #endif /* HAVE_FFDHE_Q */
00639         dh_ffdhe6144_p, sizeof(dh_ffdhe6144_p),
00640         dh_ffdhe6144_g, sizeof(dh_ffdhe6144_g)
00641     };
00642     return &ffdhe6144;
00643 }
00644 #endif
00645 
00646 #ifdef HAVE_FFDHE_8192
00647 static const byte dh_ffdhe8192_p[] = {
00648     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00649     0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
00650     0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
00651     0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
00652     0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
00653     0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
00654     0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
00655     0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
00656     0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
00657     0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
00658     0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
00659     0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
00660     0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
00661     0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
00662     0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
00663     0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
00664     0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
00665     0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
00666     0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
00667     0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
00668     0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
00669     0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
00670     0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
00671     0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
00672     0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
00673     0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
00674     0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
00675     0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
00676     0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
00677     0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
00678     0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,
00679     0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,
00680     0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,
00681     0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,
00682     0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,
00683     0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,
00684     0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,
00685     0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,
00686     0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,
00687     0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,
00688     0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,
00689     0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,
00690     0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,
00691     0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,
00692     0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,
00693     0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,
00694     0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1,
00695     0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB,
00696     0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6,
00697     0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18,
00698     0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04,
00699     0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A,
00700     0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A,
00701     0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32,
00702     0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4,
00703     0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38,
00704     0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A,
00705     0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C,
00706     0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC,
00707     0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF,
00708     0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B,
00709     0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1,
00710     0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02,
00711     0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A,
00712     0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A,
00713     0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6,
00714     0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8,
00715     0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C,
00716     0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A,
00717     0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71,
00718     0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F,
00719     0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77,
00720     0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10,
00721     0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8,
00722     0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3,
00723     0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E,
00724     0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3,
00725     0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4,
00726     0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1,
00727     0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92,
00728     0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6,
00729     0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82,
00730     0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE,
00731     0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C,
00732     0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E,
00733     0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46,
00734     0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A,
00735     0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17,
00736     0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03,
00737     0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04,
00738     0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6,
00739     0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69,
00740     0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1,
00741     0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4,
00742     0xA4, 0x0E, 0x32, 0x9C, 0xCF, 0xF4, 0x6A, 0xAA,
00743     0x36, 0xAD, 0x00, 0x4C, 0xF6, 0x00, 0xC8, 0x38,
00744     0x1E, 0x42, 0x5A, 0x31, 0xD9, 0x51, 0xAE, 0x64,
00745     0xFD, 0xB2, 0x3F, 0xCE, 0xC9, 0x50, 0x9D, 0x43,
00746     0x68, 0x7F, 0xEB, 0x69, 0xED, 0xD1, 0xCC, 0x5E,
00747     0x0B, 0x8C, 0xC3, 0xBD, 0xF6, 0x4B, 0x10, 0xEF,
00748     0x86, 0xB6, 0x31, 0x42, 0xA3, 0xAB, 0x88, 0x29,
00749     0x55, 0x5B, 0x2F, 0x74, 0x7C, 0x93, 0x26, 0x65,
00750     0xCB, 0x2C, 0x0F, 0x1C, 0xC0, 0x1B, 0xD7, 0x02,
00751     0x29, 0x38, 0x88, 0x39, 0xD2, 0xAF, 0x05, 0xE4,
00752     0x54, 0x50, 0x4A, 0xC7, 0x8B, 0x75, 0x82, 0x82,
00753     0x28, 0x46, 0xC0, 0xBA, 0x35, 0xC3, 0x5F, 0x5C,
00754     0x59, 0x16, 0x0C, 0xC0, 0x46, 0xFD, 0x82, 0x51,
00755     0x54, 0x1F, 0xC6, 0x8C, 0x9C, 0x86, 0xB0, 0x22,
00756     0xBB, 0x70, 0x99, 0x87, 0x6A, 0x46, 0x0E, 0x74,
00757     0x51, 0xA8, 0xA9, 0x31, 0x09, 0x70, 0x3F, 0xEE,
00758     0x1C, 0x21, 0x7E, 0x6C, 0x38, 0x26, 0xE5, 0x2C,
00759     0x51, 0xAA, 0x69, 0x1E, 0x0E, 0x42, 0x3C, 0xFC,
00760     0x99, 0xE9, 0xE3, 0x16, 0x50, 0xC1, 0x21, 0x7B,
00761     0x62, 0x48, 0x16, 0xCD, 0xAD, 0x9A, 0x95, 0xF9,
00762     0xD5, 0xB8, 0x01, 0x94, 0x88, 0xD9, 0xC0, 0xA0,
00763     0xA1, 0xFE, 0x30, 0x75, 0xA5, 0x77, 0xE2, 0x31,
00764     0x83, 0xF8, 0x1D, 0x4A, 0x3F, 0x2F, 0xA4, 0x57,
00765     0x1E, 0xFC, 0x8C, 0xE0, 0xBA, 0x8A, 0x4F, 0xE8,
00766     0xB6, 0x85, 0x5D, 0xFE, 0x72, 0xB0, 0xA6, 0x6E,
00767     0xDE, 0xD2, 0xFB, 0xAB, 0xFB, 0xE5, 0x8A, 0x30,
00768     0xFA, 0xFA, 0xBE, 0x1C, 0x5D, 0x71, 0xA8, 0x7E,
00769     0x2F, 0x74, 0x1E, 0xF8, 0xC1, 0xFE, 0x86, 0xFE,
00770     0xA6, 0xBB, 0xFD, 0xE5, 0x30, 0x67, 0x7F, 0x0D,
00771     0x97, 0xD1, 0x1D, 0x49, 0xF7, 0xA8, 0x44, 0x3D,
00772     0x08, 0x22, 0xE5, 0x06, 0xA9, 0xF4, 0x61, 0x4E,
00773     0x01, 0x1E, 0x2A, 0x94, 0x83, 0x8F, 0xF8, 0x8C,
00774     0xD6, 0x8C, 0x8B, 0xB7, 0xC5, 0xC6, 0x42, 0x4C,
00775     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
00776 };
00777 static const byte dh_ffdhe8192_g[] = { 0x02 };
00778 #ifdef HAVE_FFDHE_Q
00779 static const byte dh_ffdhe8192_q[] = {
00780     0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00781     0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
00782     0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
00783     0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
00784     0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
00785     0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
00786     0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
00787     0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
00788     0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
00789     0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
00790     0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
00791     0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
00792     0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
00793     0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
00794     0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
00795     0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
00796     0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
00797     0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
00798     0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
00799     0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
00800     0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
00801     0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
00802     0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
00803     0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
00804     0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
00805     0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
00806     0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
00807     0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
00808     0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
00809     0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
00810     0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,
00811     0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,
00812     0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,
00813     0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,
00814     0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,
00815     0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,
00816     0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,
00817     0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,
00818     0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,
00819     0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,
00820     0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,
00821     0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,
00822     0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,
00823     0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,
00824     0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,
00825     0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,
00826     0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78,
00827     0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D,
00828     0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB,
00829     0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C,
00830     0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02,
00831     0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D,
00832     0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5,
00833     0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19,
00834     0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62,
00835     0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C,
00836     0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD,
00837     0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E,
00838     0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66,
00839     0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7,
00840     0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35,
00841     0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70,
00842     0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x06, 0xEC, 0x81,
00843     0x05, 0xFE, 0xB2, 0x5B, 0x22, 0x81, 0xB6, 0x3D,
00844     0x27, 0x33, 0xBE, 0x96, 0x1C, 0x29, 0x95, 0x1D,
00845     0x11, 0xDD, 0x22, 0x21, 0x65, 0x7A, 0x9F, 0x53,
00846     0x1D, 0xDA, 0x2A, 0x19, 0x4D, 0xBB, 0x12, 0x64,
00847     0x48, 0xBD, 0xEE, 0xB2, 0x58, 0xE0, 0x7E, 0xA6,
00848     0x59, 0xC7, 0x46, 0x19, 0xA6, 0x38, 0x0E, 0x1D,
00849     0x66, 0xD6, 0x83, 0x2B, 0xFE, 0x67, 0xF6, 0x38,
00850     0xCD, 0x8F, 0xAE, 0x1F, 0x27, 0x23, 0x02, 0x0F,
00851     0x9C, 0x40, 0xA3, 0xFD, 0xA6, 0x7E, 0xDA, 0x3B,
00852     0xD2, 0x92, 0x38, 0xFB, 0xD4, 0xD4, 0xB4, 0x88,
00853     0x5C, 0x2A, 0x99, 0x17, 0x6D, 0xB1, 0xA0, 0x6C,
00854     0x50, 0x07, 0x78, 0x49, 0x1A, 0x82, 0x88, 0xF1,
00855     0x85, 0x5F, 0x60, 0xFF, 0xFC, 0xF1, 0xD1, 0x37,
00856     0x3F, 0xD9, 0x4F, 0xC6, 0x0C, 0x18, 0x11, 0xE1,
00857     0xAC, 0x3F, 0x1C, 0x6D, 0x00, 0x3B, 0xEC, 0xDA,
00858     0x3B, 0x1F, 0x27, 0x25, 0xCA, 0x59, 0x5D, 0xE0,
00859     0xCA, 0x63, 0x32, 0x8F, 0x3B, 0xE5, 0x7C, 0xC9,
00860     0x77, 0x55, 0x60, 0x11, 0x95, 0x14, 0x0D, 0xFB,
00861     0x59, 0xD3, 0x9C, 0xE0, 0x91, 0x30, 0x8B, 0x41,
00862     0x05, 0x74, 0x6D, 0xAC, 0x23, 0xD3, 0x3E, 0x5F,
00863     0x7C, 0xE4, 0x84, 0x8D, 0xA3, 0x16, 0xA9, 0xC6,
00864     0x6B, 0x95, 0x81, 0xBA, 0x35, 0x73, 0xBF, 0xAF,
00865     0x31, 0x14, 0x96, 0x18, 0x8A, 0xB1, 0x54, 0x23,
00866     0x28, 0x2E, 0xE4, 0x16, 0xDC, 0x2A, 0x19, 0xC5,
00867     0x72, 0x4F, 0xA9, 0x1A, 0xE4, 0xAD, 0xC8, 0x8B,
00868     0xC6, 0x67, 0x96, 0xEA, 0xE5, 0x67, 0x7A, 0x01,
00869     0xF6, 0x4E, 0x8C, 0x08, 0x63, 0x13, 0x95, 0x82,
00870     0x2D, 0x9D, 0xB8, 0xFC, 0xEE, 0x35, 0xC0, 0x6B,
00871     0x1F, 0xEE, 0xA5, 0x47, 0x4D, 0x6D, 0x8F, 0x34,
00872     0xB1, 0x53, 0x4A, 0x93, 0x6A, 0x18, 0xB0, 0xE0,
00873     0xD2, 0x0E, 0xAB, 0x86, 0xBC, 0x9C, 0x6D, 0x6A,
00874     0x52, 0x07, 0x19, 0x4E, 0x67, 0xFA, 0x35, 0x55,
00875     0x1B, 0x56, 0x80, 0x26, 0x7B, 0x00, 0x64, 0x1C,
00876     0x0F, 0x21, 0x2D, 0x18, 0xEC, 0xA8, 0xD7, 0x32,
00877     0x7E, 0xD9, 0x1F, 0xE7, 0x64, 0xA8, 0x4E, 0xA1,
00878     0xB4, 0x3F, 0xF5, 0xB4, 0xF6, 0xE8, 0xE6, 0x2F,
00879     0x05, 0xC6, 0x61, 0xDE, 0xFB, 0x25, 0x88, 0x77,
00880     0xC3, 0x5B, 0x18, 0xA1, 0x51, 0xD5, 0xC4, 0x14,
00881     0xAA, 0xAD, 0x97, 0xBA, 0x3E, 0x49, 0x93, 0x32,
00882     0xE5, 0x96, 0x07, 0x8E, 0x60, 0x0D, 0xEB, 0x81,
00883     0x14, 0x9C, 0x44, 0x1C, 0xE9, 0x57, 0x82, 0xF2,
00884     0x2A, 0x28, 0x25, 0x63, 0xC5, 0xBA, 0xC1, 0x41,
00885     0x14, 0x23, 0x60, 0x5D, 0x1A, 0xE1, 0xAF, 0xAE,
00886     0x2C, 0x8B, 0x06, 0x60, 0x23, 0x7E, 0xC1, 0x28,
00887     0xAA, 0x0F, 0xE3, 0x46, 0x4E, 0x43, 0x58, 0x11,
00888     0x5D, 0xB8, 0x4C, 0xC3, 0xB5, 0x23, 0x07, 0x3A,
00889     0x28, 0xD4, 0x54, 0x98, 0x84, 0xB8, 0x1F, 0xF7,
00890     0x0E, 0x10, 0xBF, 0x36, 0x1C, 0x13, 0x72, 0x96,
00891     0x28, 0xD5, 0x34, 0x8F, 0x07, 0x21, 0x1E, 0x7E,
00892     0x4C, 0xF4, 0xF1, 0x8B, 0x28, 0x60, 0x90, 0xBD,
00893     0xB1, 0x24, 0x0B, 0x66, 0xD6, 0xCD, 0x4A, 0xFC,
00894     0xEA, 0xDC, 0x00, 0xCA, 0x44, 0x6C, 0xE0, 0x50,
00895     0x50, 0xFF, 0x18, 0x3A, 0xD2, 0xBB, 0xF1, 0x18,
00896     0xC1, 0xFC, 0x0E, 0xA5, 0x1F, 0x97, 0xD2, 0x2B,
00897     0x8F, 0x7E, 0x46, 0x70, 0x5D, 0x45, 0x27, 0xF4,
00898     0x5B, 0x42, 0xAE, 0xFF, 0x39, 0x58, 0x53, 0x37,
00899     0x6F, 0x69, 0x7D, 0xD5, 0xFD, 0xF2, 0xC5, 0x18,
00900     0x7D, 0x7D, 0x5F, 0x0E, 0x2E, 0xB8, 0xD4, 0x3F,
00901     0x17, 0xBA, 0x0F, 0x7C, 0x60, 0xFF, 0x43, 0x7F,
00902     0x53, 0x5D, 0xFE, 0xF2, 0x98, 0x33, 0xBF, 0x86,
00903     0xCB, 0xE8, 0x8E, 0xA4, 0xFB, 0xD4, 0x22, 0x1E,
00904     0x84, 0x11, 0x72, 0x83, 0x54, 0xFA, 0x30, 0xA7,
00905     0x00, 0x8F, 0x15, 0x4A, 0x41, 0xC7, 0xFC, 0x46,
00906     0x6B, 0x46, 0x45, 0xDB, 0xE2, 0xE3, 0x21, 0x26,
00907     0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
00908 };
00909 #endif /* HAVE_FFDHE_Q */
00910 
00911 const DhParams* wc_Dh_ffdhe8192_Get(void)
00912 {
00913     static const DhParams ffdhe8192 = {
00914         #ifdef HAVE_FFDHE_Q
00915             dh_ffdhe8192_q, sizeof(dh_ffdhe8192_q),
00916         #endif /* HAVE_FFDHE_Q */
00917         dh_ffdhe8192_p, sizeof(dh_ffdhe8192_p),
00918         dh_ffdhe8192_g, sizeof(dh_ffdhe8192_g)
00919     };
00920     return &ffdhe8192;
00921 }
00922 #endif
00923 
00924 int wc_InitDhKey_ex(DhKey* key, void* heap, int devId)
00925 {
00926     int ret = 0;
00927 
00928     if (key == NULL)
00929         return BAD_FUNC_ARG;
00930 
00931     key->heap = heap; /* for XMALLOC/XFREE in future */
00932 
00933 #if !defined(WOLFSSL_QT) && !defined(OPENSSL_ALL)
00934     if (mp_init_multi(&key->p, &key->g, &key->q, NULL, NULL, NULL) != MP_OKAY)
00935 #else
00936     if (mp_init_multi(&key->p,&key->g,&key->q,&key->pub,&key->priv,NULL) != MP_OKAY)
00937 #endif
00938         return MEMORY_E;
00939 
00940 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
00941     /* handle as async */
00942     ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_DH,
00943         key->heap, devId);
00944 #else
00945     (void)devId;
00946 #endif
00947 
00948     return ret;
00949 }
00950 
00951 int wc_InitDhKey(DhKey* key)
00952 {
00953     return wc_InitDhKey_ex(key, NULL, INVALID_DEVID);
00954 }
00955 
00956 
00957 int wc_FreeDhKey(DhKey* key)
00958 {
00959     if (key) {
00960         mp_clear(&key->p);
00961         mp_clear(&key->g);
00962         mp_clear(&key->q);
00963 
00964     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
00965         wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_DH);
00966     #endif
00967     }
00968     return 0;
00969 }
00970 
00971 
00972 #ifndef WC_NO_RNG
00973 /* if defined to not use floating point values do not compile in */
00974 #ifndef WOLFSSL_DH_CONST
00975     static word32 DiscreteLogWorkFactor(word32 n)
00976     {
00977         /* assuming discrete log takes about the same time as factoring */
00978         if (n < 5)
00979             return 0;
00980         else
00981             return (word32)(2.4 * XPOW((double)n, 1.0/3.0) *
00982                     XPOW(XLOG((double)n), 2.0/3.0) - 5);
00983     }
00984 #endif /* WOLFSSL_DH_CONST*/
00985 
00986 
00987 /* if not using fixed points use DiscreteLogWorkFactor function for unusual size
00988    otherwise round up on size needed */
00989 #ifndef WOLFSSL_DH_CONST
00990     #define WOLFSSL_DH_ROUND(x)
00991 #else
00992     #define WOLFSSL_DH_ROUND(x) \
00993         do {                    \
00994             if (x % 128) {      \
00995                 x &= 0xffffff80;\
00996                 x += 128;       \
00997             }                   \
00998         }                       \
00999         while (0)
01000 #endif
01001 
01002 
01003 #ifndef WOLFSSL_NO_DH186
01004 /* validate that (L,N) match allowed sizes from SP 800-56A, Section 5.5.1.1.
01005  * modLen - represents L, the size of p in bits
01006  * divLen - represents N, the size of q in bits
01007  * return 0 on success, -1 on error */
01008 static int CheckDhLN(int modLen, int divLen)
01009 {
01010     int ret = -1;
01011 
01012     switch (modLen) {
01013         /* FA */
01014         case 1024:
01015             if (divLen == 160)
01016                 ret = 0;
01017             break;
01018         /* FB, FC */
01019         case 2048:
01020             if (divLen == 224 || divLen == 256)
01021                 ret = 0;
01022             break;
01023         default:
01024             break;
01025     }
01026 
01027     return ret;
01028 }
01029 
01030 
01031 /* Create DH private key
01032  *
01033  * Based on NIST FIPS 186-4,
01034  * "B.1.1 Key Pair Generation Using Extra Random Bits"
01035  *
01036  * dh     - pointer to initialized DhKey structure, needs to have dh->q
01037  * rng    - pointer to initialized WC_RNG structure
01038  * priv   - output location for generated private key
01039  * privSz - IN/OUT, size of priv buffer, size of generated private key
01040  *
01041  * return 0 on success, negative on error */
01042 static int GeneratePrivateDh186(DhKey* key, WC_RNG* rng, byte* priv,
01043                                 word32* privSz)
01044 {
01045     byte* cBuf;
01046     int qSz, pSz, cSz, err;
01047 #ifdef WOLFSSL_SMALL_STACK
01048     mp_int* tmpQ = NULL;
01049     mp_int* tmpX = NULL;
01050 #else
01051     mp_int tmpQ[1], tmpX[1];
01052 #endif
01053 
01054     /* Parameters validated in calling functions. */
01055 
01056     if (mp_iszero(&key->q) == MP_YES) {
01057         WOLFSSL_MSG("DH q parameter needed for FIPS 186-4 key generation");
01058         return BAD_FUNC_ARG;
01059     }
01060 
01061     qSz = mp_unsigned_bin_size(&key->q);
01062     pSz = mp_unsigned_bin_size(&key->p);
01063 
01064     /* verify (L,N) pair bit lengths */
01065     if (CheckDhLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0) {
01066         WOLFSSL_MSG("DH param sizes do not match SP 800-56A requirements");
01067         return BAD_FUNC_ARG;
01068     }
01069 
01070     /* generate extra 64 bits so that bias from mod function is negligible */
01071     cSz = qSz + (64 / WOLFSSL_BIT_SIZE);
01072     cBuf = (byte*)XMALLOC(cSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
01073     if (cBuf == NULL) {
01074         return MEMORY_E;
01075     }
01076 #ifdef WOLFSSL_SMALL_STACK
01077     tmpQ = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
01078     if (tmpQ == NULL) {
01079         XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
01080         return MEMORY_E;
01081     }
01082     tmpX = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
01083     if (tmpX == NULL) {
01084         XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
01085         XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
01086         return MEMORY_E;
01087     }
01088 #endif
01089 
01090 
01091     if ((err = mp_init_multi(tmpX, tmpQ, NULL, NULL, NULL, NULL))
01092                    != MP_OKAY) {
01093         XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
01094 #ifdef WOLFSSL_SMALL_STACK
01095         XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
01096         XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);
01097 #endif
01098         return err;
01099     }
01100 
01101     do {
01102         /* generate N+64 bits (c) from RBG into tmpX, making sure positive.
01103          * Hash_DRBG uses SHA-256 which matches maximum
01104          * requested_security_strength of (L,N) */
01105         err = wc_RNG_GenerateBlock(rng, cBuf, cSz);
01106         if (err == MP_OKAY)
01107             err = mp_read_unsigned_bin(tmpX, cBuf, cSz);
01108         if (err != MP_OKAY) {
01109             mp_clear(tmpX);
01110             mp_clear(tmpQ);
01111             XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
01112 #ifdef WOLFSSL_SMALL_STACK
01113             XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
01114             XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);
01115 #endif
01116             return err;
01117         }
01118     } while (mp_cmp_d(tmpX, 1) != MP_GT);
01119 
01120     ForceZero(cBuf, cSz);
01121     XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
01122 
01123     /* tmpQ = q - 1 */
01124     if (err == MP_OKAY)
01125         err = mp_copy(&key->q, tmpQ);
01126 
01127     if (err == MP_OKAY)
01128         err = mp_sub_d(tmpQ, 1, tmpQ);
01129 
01130     /* x = c mod (q-1), tmpX holds c */
01131     if (err == MP_OKAY)
01132         err = mp_mod(tmpX, tmpQ, tmpX);
01133 
01134     /* x = c mod (q-1) + 1 */
01135     if (err == MP_OKAY)
01136         err = mp_add_d(tmpX, 1, tmpX);
01137 
01138     /* copy tmpX into priv */
01139     if (err == MP_OKAY) {
01140         pSz = mp_unsigned_bin_size(tmpX);
01141         if (pSz > (int)*privSz) {
01142             WOLFSSL_MSG("DH private key output buffer too small");
01143             err = BAD_FUNC_ARG;
01144         } else {
01145             *privSz = pSz;
01146             err = mp_to_unsigned_bin(tmpX, priv);
01147         }
01148     }
01149 
01150     mp_forcezero(tmpX);
01151     mp_clear(tmpX);
01152     mp_clear(tmpQ);
01153 #ifdef WOLFSSL_SMALL_STACK
01154     XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
01155     XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);
01156 #endif
01157 
01158     return err;
01159 }
01160 #endif /* WOLFSSL_NO_DH186 */
01161 #endif /* !WC_NO_RNG */
01162 
01163 static int GeneratePrivateDh(DhKey* key, WC_RNG* rng, byte* priv,
01164                              word32* privSz)
01165 {
01166 #ifndef WC_NO_RNG
01167     int ret = 0;
01168     word32 sz = 0;
01169 
01170 #ifndef WOLFSSL_NO_DH186
01171     if (mp_iszero(&key->q) == MP_NO) {
01172 
01173         /* q param available, use NIST FIPS 186-4, "B.1.1 Key Pair
01174          * Generation Using Extra Random Bits" */
01175         ret = GeneratePrivateDh186(key, rng, priv, privSz);
01176 
01177     } else
01178 #endif
01179     {
01180 
01181         sz = mp_unsigned_bin_size(&key->p);
01182 
01183         /* Table of predetermined values from the operation
01184            2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) /
01185            WOLFSSL_BIT_SIZE + 1
01186            Sizes in table checked against RFC 3526
01187          */
01188         WOLFSSL_DH_ROUND(sz); /* if using fixed points only, then round up */
01189         switch (sz) {
01190             case 128:  sz = 21; break;
01191             case 256:  sz = 29; break;
01192             case 384:  sz = 34; break;
01193             case 512:  sz = 39; break;
01194             case 640:  sz = 42; break;
01195             case 768:  sz = 46; break;
01196             case 896:  sz = 49; break;
01197             case 1024: sz = 52; break;
01198             default:
01199             #ifndef WOLFSSL_DH_CONST
01200                 /* if using floating points and size of p is not in table */
01201                 sz = min(sz, 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) /
01202                                            WOLFSSL_BIT_SIZE + 1);
01203                 break;
01204             #else
01205                 return BAD_FUNC_ARG;
01206             #endif
01207         }
01208 
01209         ret = wc_RNG_GenerateBlock(rng, priv, sz);
01210 
01211         if (ret == 0) {
01212             priv[0] |= 0x0C;
01213             *privSz = sz;
01214         }
01215     }
01216 
01217     return ret;
01218 #else
01219     (void)key;
01220     (void)rng;
01221     (void)priv;
01222     (void)privSz;
01223     return NOT_COMPILED_IN;
01224 #endif /* WC_NO_RNG */
01225 }
01226 
01227 
01228 static int GeneratePublicDh(DhKey* key, byte* priv, word32 privSz,
01229     byte* pub, word32* pubSz)
01230 {
01231     int ret = 0;
01232 #ifndef WOLFSSL_SP_MATH
01233 #ifdef WOLFSSL_SMALL_STACK
01234     mp_int* x;
01235     mp_int* y;
01236 #else
01237     mp_int x[1];
01238     mp_int y[1];
01239 #endif
01240 #endif
01241 
01242 #ifdef WOLFSSL_HAVE_SP_DH
01243 #ifndef WOLFSSL_SP_NO_2048
01244     if (mp_count_bits(&key->p) == 2048)
01245         return sp_DhExp_2048(&key->g, priv, privSz, &key->p, pub, pubSz);
01246 #endif
01247 #ifndef WOLFSSL_SP_NO_3072
01248     if (mp_count_bits(&key->p) == 3072)
01249         return sp_DhExp_3072(&key->g, priv, privSz, &key->p, pub, pubSz);
01250 #endif
01251 #ifdef WOLFSSL_SP_4096
01252     if (mp_count_bits(&key->p) == 4096)
01253         return sp_DhExp_4096(&key->g, priv, privSz, &key->p, pub, pubSz);
01254 #endif
01255 #endif
01256 
01257 #ifndef WOLFSSL_SP_MATH
01258 #ifdef WOLFSSL_SMALL_STACK
01259     x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
01260     if (x == NULL)
01261         return MEMORY_E;
01262     y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
01263     if (y == NULL) {
01264         XFREE(x, key->heap, DYNAMIC_TYPE_DH);
01265         return MEMORY_E;
01266     }
01267 #endif
01268     if (mp_init_multi(x, y, 0, 0, 0, 0) != MP_OKAY) {
01269     #ifdef WOLFSSL_SMALL_STACK
01270         XFREE(y, key->heap, DYNAMIC_TYPE_DH);
01271         XFREE(x, key->heap, DYNAMIC_TYPE_DH);
01272     #endif
01273         return MP_INIT_E;
01274     }
01275 
01276     if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY)
01277         ret = MP_READ_E;
01278 
01279     if (ret == 0 && mp_exptmod(&key->g, x, &key->p, y) != MP_OKAY)
01280         ret = MP_EXPTMOD_E;
01281 
01282     if (ret == 0 && mp_to_unsigned_bin(y, pub) != MP_OKAY)
01283         ret = MP_TO_E;
01284 
01285     if (ret == 0)
01286         *pubSz = mp_unsigned_bin_size(y);
01287 
01288     mp_clear(y);
01289     mp_clear(x);
01290 #ifdef WOLFSSL_SMALL_STACK
01291     XFREE(y, key->heap, DYNAMIC_TYPE_DH);
01292     XFREE(x, key->heap, DYNAMIC_TYPE_DH);
01293 #endif
01294 #else
01295     ret = WC_KEY_SIZE_E;
01296 #endif
01297 
01298     return ret;
01299 }
01300 
01301 static int wc_DhGenerateKeyPair_Sync(DhKey* key, WC_RNG* rng,
01302     byte* priv, word32* privSz, byte* pub, word32* pubSz)
01303 {
01304     int ret;
01305 
01306     if (key == NULL || rng == NULL || priv == NULL || privSz == NULL ||
01307         pub == NULL || pubSz == NULL) {
01308         return BAD_FUNC_ARG;
01309     }
01310 
01311     ret = GeneratePrivateDh(key, rng, priv, privSz);
01312 
01313     return (ret != 0) ? ret : GeneratePublicDh(key, priv, *privSz, pub, pubSz);
01314 }
01315 
01316 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
01317 static int wc_DhGenerateKeyPair_Async(DhKey* key, WC_RNG* rng,
01318     byte* priv, word32* privSz, byte* pub, word32* pubSz)
01319 {
01320     int ret;
01321 
01322 #if defined(HAVE_INTEL_QA)
01323     word32 pBits;
01324 
01325     /* QAT DH sizes: 768, 1024, 1536, 2048, 3072 and 4096 bits */
01326     pBits = mp_unsigned_bin_size(&key->p) * 8;
01327     if (pBits == 768 ||  pBits == 1024 || pBits == 1536 ||
01328         pBits == 2048 || pBits == 3072 || pBits == 4096) {
01329         mp_int x;
01330 
01331         ret = mp_init(&x);
01332         if (ret != MP_OKAY)
01333             return ret;
01334 
01335         ret = GeneratePrivateDh(key, rng, priv, privSz);
01336         if (ret == 0)
01337             ret = mp_read_unsigned_bin(&x, priv, *privSz);
01338         if (ret == MP_OKAY)
01339             ret = wc_mp_to_bigint(&x, &x.raw);
01340         if (ret == MP_OKAY)
01341             ret = wc_mp_to_bigint(&key->p, &key->p.raw);
01342         if (ret == MP_OKAY)
01343             ret = wc_mp_to_bigint(&key->g, &key->g.raw);
01344         if (ret == MP_OKAY)
01345             ret = IntelQaDhKeyGen(&key->asyncDev, &key->p.raw, &key->g.raw,
01346                 &x.raw, pub, pubSz);
01347         mp_clear(&x);
01348 
01349         return ret;
01350     }
01351 
01352 #elif defined(HAVE_CAVIUM)
01353     /* TODO: Not implemented - use software for now */
01354 
01355 #else /* WOLFSSL_ASYNC_CRYPT_TEST */
01356     if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_DH_GEN)) {
01357         WC_ASYNC_TEST* testDev = &key->asyncDev.test;
01358         testDev->dhGen.key = key;
01359         testDev->dhGen.rng = rng;
01360         testDev->dhGen.priv = priv;
01361         testDev->dhGen.privSz = privSz;
01362         testDev->dhGen.pub = pub;
01363         testDev->dhGen.pubSz = pubSz;
01364         return WC_PENDING_E;
01365     }
01366 #endif
01367 
01368     /* otherwise use software DH */
01369     ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz);
01370 
01371     return ret;
01372 }
01373 #endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_DH */
01374 
01375 
01376 /* Check DH Public Key for invalid numbers, optionally allowing
01377  * the public key to be checked against the large prime (q).
01378  * Check per process in SP 800-56Ar3, section 5.6.2.3.1.
01379  *
01380  * key     DH key group parameters.
01381  * pub     Public Key.
01382  * pubSz   Public Key size.
01383  * prime   Large prime (q), optionally NULL to skip check
01384  * primeSz Size of large prime
01385  *
01386  *  returns 0 on success or error code
01387  */
01388 int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz,
01389                         const byte* prime, word32 primeSz)
01390 {
01391     int ret = 0;
01392 #ifdef WOLFSSL_SMALL_STACK
01393     mp_int* y = NULL;
01394     mp_int* p = NULL;
01395     mp_int* q = NULL;
01396 #else
01397     mp_int y[1];
01398     mp_int p[1];
01399     mp_int q[1];
01400 #endif
01401 
01402     if (key == NULL || pub == NULL) {
01403         return BAD_FUNC_ARG;
01404     }
01405 
01406 #ifdef WOLFSSL_SMALL_STACK
01407     y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
01408     if (y == NULL)
01409         return MEMORY_E;
01410     p = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
01411     if (p == NULL) {
01412         XFREE(y, key->heap, DYNAMIC_TYPE_DH);
01413         return MEMORY_E;
01414     }
01415     q = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
01416     if (q == NULL) {
01417         XFREE(p, key->heap, DYNAMIC_TYPE_DH);
01418         XFREE(y, key->heap, DYNAMIC_TYPE_DH);
01419         return MEMORY_E;
01420     }
01421 #endif
01422 
01423     if (mp_init_multi(y, p, q, NULL, NULL, NULL) != MP_OKAY) {
01424     #ifdef WOLFSSL_SMALL_STACK
01425         XFREE(q, key->heap, DYNAMIC_TYPE_DH);
01426         XFREE(p, key->heap, DYNAMIC_TYPE_DH);
01427         XFREE(y, key->heap, DYNAMIC_TYPE_DH);
01428     #endif
01429         return MP_INIT_E;
01430     }
01431 
01432     if (mp_read_unsigned_bin(y, pub, pubSz) != MP_OKAY) {
01433         ret = MP_READ_E;
01434     }
01435 
01436     if (ret == 0 && prime != NULL) {
01437         if (mp_read_unsigned_bin(q, prime, primeSz) != MP_OKAY)
01438             ret = MP_READ_E;
01439 
01440     } else if (mp_iszero(&key->q) == MP_NO) {
01441         /* use q available in DhKey */
01442         if (mp_copy(&key->q, q) != MP_OKAY)
01443             ret = MP_INIT_E;
01444     }
01445 
01446     /* SP 800-56Ar3, section 5.6.2.3.1, process step 1 */
01447     /* pub (y) should not be 0 or 1 */
01448     if (ret == 0 && mp_cmp_d(y, 2) == MP_LT) {
01449         ret = MP_CMP_E;
01450     }
01451 
01452     /* pub (y) shouldn't be greater than or equal to p - 1 */
01453     if (ret == 0 && mp_copy(&key->p, p) != MP_OKAY) {
01454         ret = MP_INIT_E;
01455     }
01456     if (ret == 0 && mp_sub_d(p, 2, p) != MP_OKAY) {
01457         ret = MP_SUB_E;
01458     }
01459     if (ret == 0 && mp_cmp(y, p) == MP_GT) {
01460         ret = MP_CMP_E;
01461     }
01462 
01463     if (ret == 0 && (prime != NULL || (mp_iszero(&key->q) == MP_NO) )) {
01464 
01465         /* restore key->p into p */
01466         if (mp_copy(&key->p, p) != MP_OKAY)
01467             ret = MP_INIT_E;
01468     }
01469 
01470     if (ret == 0 && prime != NULL) {
01471 #ifdef WOLFSSL_HAVE_SP_DH
01472 #ifndef WOLFSSL_SP_NO_2048
01473         if (mp_count_bits(&key->p) == 2048) {
01474             ret = sp_ModExp_2048(y, q, p, y);
01475             if (ret != 0)
01476                 ret = MP_EXPTMOD_E;
01477         }
01478         else
01479 #endif
01480 #ifndef WOLFSSL_SP_NO_3072
01481         if (mp_count_bits(&key->p) == 3072) {
01482             ret = sp_ModExp_3072(y, q, p, y);
01483             if (ret != 0)
01484                 ret = MP_EXPTMOD_E;
01485         }
01486         else
01487 #endif
01488 #ifdef WOLFSSL_SP_NO_4096
01489         if (mp_count_bits(&key->p) == 4096) {
01490             ret = sp_ModExp_4096(y, q, p, y);
01491             if (ret != 0)
01492                 ret = MP_EXPTMOD_E;
01493         }
01494         else
01495 #endif
01496 #endif
01497 
01498         {
01499     /* SP 800-56Ar3, section 5.6.2.3.1, process step 2 */
01500 #ifndef WOLFSSL_SP_MATH
01501             /* calculate (y^q) mod(p), store back into y */
01502             if (mp_exptmod(y, q, p, y) != MP_OKAY)
01503                 ret = MP_EXPTMOD_E;
01504 #else
01505             ret = WC_KEY_SIZE_E;
01506 #endif
01507         }
01508 
01509         /* verify above == 1 */
01510         if (ret == 0 && mp_cmp_d(y, 1) != MP_EQ)
01511             ret = MP_CMP_E;
01512     }
01513 
01514     mp_clear(y);
01515     mp_clear(p);
01516     mp_clear(q);
01517 #ifdef WOLFSSL_SMALL_STACK
01518     XFREE(q, key->heap, DYNAMIC_TYPE_DH);
01519     XFREE(p, key->heap, DYNAMIC_TYPE_DH);
01520     XFREE(y, key->heap, DYNAMIC_TYPE_DH);
01521 #endif
01522 
01523     return ret;
01524 }
01525 
01526 
01527 /* Check DH Public Key for invalid numbers
01528  *
01529  * key   DH key group parameters.
01530  * pub   Public Key.
01531  * pubSz Public Key size.
01532  *
01533  *  returns 0 on success or error code
01534  */
01535 int wc_DhCheckPubKey(DhKey* key, const byte* pub, word32 pubSz)
01536 {
01537     return wc_DhCheckPubKey_ex(key, pub, pubSz, NULL, 0);
01538 }
01539 
01540 
01541 /**
01542  * Quick validity check of public key value against prime.
01543  * Checks are:
01544  *   - Public key not 0 or 1
01545  *   - Public key not equal to prime or prime - 1
01546  *   - Public key not bigger than prime.
01547  *
01548  * prime    Big-endian encoding of prime in bytes.
01549  * primeSz  Size of prime in bytes.
01550  * pub      Big-endian encoding of public key in bytes.
01551  * pubSz    Size of public key in bytes.
01552  */
01553 int wc_DhCheckPubValue(const byte* prime, word32 primeSz, const byte* pub,
01554                        word32 pubSz)
01555 {
01556     int ret = 0;
01557     word32 i;
01558 
01559     for (i = 0; i < pubSz && pub[i] == 0; i++) {
01560     }
01561     pubSz -= i;
01562     pub += i;
01563 
01564     if (pubSz == 0 || (pubSz == 1 && pub[0] == 1))
01565         ret = MP_VAL;
01566     else if (pubSz == primeSz) {
01567         for (i = 0; i < pubSz-1 && pub[i] == prime[i]; i++) {
01568         }
01569         if (i == pubSz-1 && (pub[i] == prime[i] || pub[i] == prime[i] - 1))
01570             ret = MP_VAL;
01571         else if (pub[i] > prime[i])
01572             ret = MP_VAL;
01573     }
01574     else if (pubSz > primeSz)
01575         ret = MP_VAL;
01576 
01577     return ret;
01578 }
01579 
01580 
01581 /* Check DH Private Key for invalid numbers, optionally allowing
01582  * the private key to be checked against the large prime (q).
01583  * Check per process in SP 800-56Ar3, section 5.6.2.1.2.
01584  *
01585  * key     DH key group parameters.
01586  * priv    Private Key.
01587  * privSz  Private Key size.
01588  * prime   Large prime (q), optionally NULL to skip check
01589  * primeSz Size of large prime
01590  *
01591  *  returns 0 on success or error code
01592  */
01593 int wc_DhCheckPrivKey_ex(DhKey* key, const byte* priv, word32 privSz,
01594                          const byte* prime, word32 primeSz)
01595 {
01596     int ret = 0;
01597 #ifdef WOLFSSL_SMALL_STACK
01598     mp_int* x = NULL;
01599     mp_int* q = NULL;
01600 #else
01601     mp_int x[1];
01602     mp_int q[1];
01603 #endif
01604 
01605     if (key == NULL || priv == NULL) {
01606         return BAD_FUNC_ARG;
01607     }
01608 
01609 #ifdef WOLFSSL_SMALL_STACK
01610     x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
01611     if (x == NULL)
01612         return MEMORY_E;
01613     q = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
01614     if (q == NULL) {
01615         XFREE(x, key->heap, DYNAMIC_TYPE_DH);
01616         return MEMORY_E;
01617     }
01618 #endif
01619 
01620     if (mp_init_multi(x, q, NULL, NULL, NULL, NULL) != MP_OKAY) {
01621     #ifdef WOLFSSL_SMALL_STACK
01622         XFREE(q, key->heap, DYNAMIC_TYPE_DH);
01623         XFREE(x, key->heap, DYNAMIC_TYPE_DH);
01624     #endif
01625         return MP_INIT_E;
01626     }
01627 
01628     if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY) {
01629         ret = MP_READ_E;
01630     }
01631 
01632     if (ret == 0) {
01633         if (prime != NULL) {
01634             if (mp_read_unsigned_bin(q, prime, primeSz) != MP_OKAY)
01635                 ret = MP_READ_E;
01636         }
01637         else if (mp_iszero(&key->q) == MP_NO) {
01638             /* use q available in DhKey */
01639             if (mp_copy(&key->q, q) != MP_OKAY)
01640                 ret = MP_INIT_E;
01641         }
01642     }
01643 
01644     /* priv (x) should not be 0 */
01645     if (ret == 0) {
01646         if (mp_cmp_d(x, 0) == MP_EQ)
01647             ret = MP_CMP_E;
01648     }
01649 
01650     if (ret == 0) {
01651         if (mp_iszero(q) == MP_NO) {
01652             /* priv (x) shouldn't be greater than q - 1 */
01653             if (ret == 0) {
01654                 if (mp_copy(&key->q, q) != MP_OKAY)
01655                     ret = MP_INIT_E;
01656             }
01657             if (ret == 0) {
01658                 if (mp_sub_d(q, 1, q) != MP_OKAY)
01659                     ret = MP_SUB_E;
01660             }
01661             if (ret == 0) {
01662                 if (mp_cmp(x, q) == MP_GT)
01663                     ret = DH_CHECK_PRIV_E;
01664             }
01665         }
01666     }
01667 
01668     mp_clear(x);
01669     mp_clear(q);
01670 #ifdef WOLFSSL_SMALL_STACK
01671     XFREE(q, key->heap, DYNAMIC_TYPE_DH);
01672     XFREE(x, key->heap, DYNAMIC_TYPE_DH);
01673 #endif
01674 
01675     return ret;
01676 }
01677 
01678 
01679 /* Check DH Private Key for invalid numbers
01680  *
01681  * key    DH key group parameters.
01682  * priv   Private Key.
01683  * privSz Private Key size.
01684  *
01685  *  returns 0 on success or error code
01686  */
01687 int wc_DhCheckPrivKey(DhKey* key, const byte* priv, word32 privSz)
01688 {
01689     return wc_DhCheckPrivKey_ex(key, priv, privSz, NULL, 0);
01690 }
01691 
01692 
01693 /* Check DH Keys for pair-wise consistency per process in
01694  * SP 800-56Ar3, section 5.6.2.1.4, method (b) for FFC.
01695  *
01696  * key    DH key group parameters.
01697  * pub    Public Key.
01698  * pubSz  Public Key size.
01699  * priv   Private Key.
01700  * privSz Private Key size.
01701  *
01702  *  returns 0 on success or error code
01703  */
01704 int wc_DhCheckKeyPair(DhKey* key, const byte* pub, word32 pubSz,
01705                       const byte* priv, word32 privSz)
01706 {
01707 #ifdef WOLFSSL_SMALL_STACK
01708     mp_int* publicKey = NULL;
01709     mp_int* privateKey = NULL;
01710     mp_int* checkKey = NULL;
01711 #else
01712     mp_int publicKey[1];
01713     mp_int privateKey[1];
01714     mp_int checkKey[1];
01715 #endif
01716     int ret = 0;
01717 
01718     if (key == NULL || pub == NULL || priv == NULL)
01719         return BAD_FUNC_ARG;
01720 
01721 #ifdef WOLFSSL_SMALL_STACK
01722     publicKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
01723     if (publicKey == NULL)
01724         return MEMORY_E;
01725     privateKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
01726     if (privateKey == NULL) {
01727         XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
01728         return MEMORY_E;
01729     }
01730     checkKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
01731     if (checkKey == NULL) {
01732         XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
01733         XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
01734         return MEMORY_E;
01735     }
01736 #endif
01737 
01738     if (mp_init_multi(publicKey, privateKey, checkKey,
01739                       NULL, NULL, NULL) != MP_OKAY) {
01740 
01741     #ifdef WOLFSSL_SMALL_STACK
01742         XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
01743         XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
01744         XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);
01745     #endif
01746         return MP_INIT_E;
01747     }
01748 
01749     /* Load the private and public keys into big integers. */
01750     if (mp_read_unsigned_bin(publicKey, pub, pubSz) != MP_OKAY ||
01751         mp_read_unsigned_bin(privateKey, priv, privSz) != MP_OKAY) {
01752 
01753         ret = MP_READ_E;
01754     }
01755 
01756     /* Calculate checkKey = g^privateKey mod p */
01757     if (ret == 0) {
01758 #ifdef WOLFSSL_HAVE_SP_DH
01759 #ifndef WOLFSSL_SP_NO_2048
01760         if (mp_count_bits(&key->p) == 2048) {
01761             ret = sp_ModExp_2048(&key->g, privateKey, &key->p, checkKey);
01762             if (ret != 0)
01763                 ret = MP_EXPTMOD_E;
01764         }
01765         else
01766 #endif
01767 #ifndef WOLFSSL_SP_NO_3072
01768         if (mp_count_bits(&key->p) == 3072) {
01769             ret = sp_ModExp_3072(&key->g, privateKey, &key->p, checkKey);
01770             if (ret != 0)
01771                 ret = MP_EXPTMOD_E;
01772         }
01773         else
01774 #endif
01775 #ifdef WOLFSSL_SP_4096
01776         if (mp_count_bits(&key->p) == 4096) {
01777             ret = sp_ModExp_4096(&key->g, privateKey, &key->p, checkKey);
01778             if (ret != 0)
01779                 ret = MP_EXPTMOD_E;
01780         }
01781         else
01782 #endif
01783 #endif
01784         {
01785 #ifndef WOLFSSL_SP_MATH
01786             if (mp_exptmod(&key->g, privateKey, &key->p, checkKey) != MP_OKAY)
01787                 ret = MP_EXPTMOD_E;
01788 #else
01789             ret = WC_KEY_SIZE_E;
01790 #endif
01791         }
01792     }
01793 
01794     /* Compare the calculated public key to the supplied check value. */
01795     if (ret == 0) {
01796         if (mp_cmp(checkKey, publicKey) != MP_EQ)
01797             ret = MP_CMP_E;
01798     }
01799 
01800     mp_forcezero(privateKey);
01801     mp_clear(privateKey);
01802     mp_clear(publicKey);
01803     mp_clear(checkKey);
01804 #ifdef WOLFSSL_SMALL_STACK
01805     XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);
01806     XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
01807     XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
01808 #endif
01809 
01810     return ret;
01811 }
01812 
01813 
01814 int wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng,
01815     byte* priv, word32* privSz, byte* pub, word32* pubSz)
01816 {
01817     int ret;
01818 
01819     if (key == NULL || rng == NULL || priv == NULL || privSz == NULL ||
01820                                                 pub == NULL || pubSz == NULL) {
01821         return BAD_FUNC_ARG;
01822     }
01823 
01824 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
01825     if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_DH) {
01826         ret = wc_DhGenerateKeyPair_Async(key, rng, priv, privSz, pub, pubSz);
01827     }
01828     else
01829 #endif
01830     {
01831         ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz);
01832     }
01833 
01834     return ret;
01835 }
01836 
01837 
01838 static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
01839     const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz)
01840 {
01841     int ret = 0;
01842 #ifdef WOLFSSL_SMALL_STACK
01843     mp_int* y;
01844 #ifndef WOLFSSL_SP_MATH
01845     mp_int* x;
01846     mp_int* z;
01847 #endif
01848 #else
01849     mp_int y[1];
01850 #ifndef WOLFSSL_SP_MATH
01851     mp_int x[1];
01852     mp_int z[1];
01853 #endif
01854 #endif
01855 
01856 #ifdef WOLFSSL_VALIDATE_FFC_IMPORT
01857     if (wc_DhCheckPrivKey(key, priv, privSz) != 0) {
01858         WOLFSSL_MSG("wc_DhAgree wc_DhCheckPrivKey failed");
01859         return DH_CHECK_PRIV_E;
01860     }
01861 
01862     if (wc_DhCheckPubKey(key, otherPub, pubSz) != 0) {
01863         WOLFSSL_MSG("wc_DhAgree wc_DhCheckPubKey failed");
01864         return DH_CHECK_PUB_E;
01865     }
01866 #endif
01867 
01868 #ifdef WOLFSSL_SMALL_STACK
01869     y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
01870     if (y == NULL)
01871         return MEMORY_E;
01872 #ifndef WOLFSSL_SP_MATH
01873     x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
01874     if (x == NULL) {
01875         XFREE(y, key->heap, DYNAMIC_TYPE_DH);
01876         return MEMORY_E;
01877     }
01878     z = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
01879     if (z == NULL) {
01880         XFREE(x, key->heap, DYNAMIC_TYPE_DH);
01881         XFREE(y, key->heap, DYNAMIC_TYPE_DH);
01882         return MEMORY_E;
01883     }
01884 #endif
01885 #endif
01886 
01887 #ifdef WOLFSSL_HAVE_SP_DH
01888 #ifndef WOLFSSL_SP_NO_2048
01889     if (mp_count_bits(&key->p) == 2048) {
01890         if (mp_init(y) != MP_OKAY)
01891             return MP_INIT_E;
01892 
01893         if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
01894             ret = MP_READ_E;
01895 
01896         if (ret == 0)
01897             ret = sp_DhExp_2048(y, priv, privSz, &key->p, agree, agreeSz);
01898 
01899         mp_clear(y);
01900     #ifdef WOLFSSL_SMALL_STACK
01901     #ifndef WOLFSSL_SP_MATH
01902         XFREE(z, key->heap, DYNAMIC_TYPE_DH);
01903         XFREE(x, key->heap, DYNAMIC_TYPE_DH);
01904     #endif
01905         XFREE(y, key->heap, DYNAMIC_TYPE_DH);
01906     #endif
01907         return ret;
01908     }
01909 #endif
01910 #ifndef WOLFSSL_SP_NO_3072
01911     if (mp_count_bits(&key->p) == 3072) {
01912         if (mp_init(y) != MP_OKAY)
01913             return MP_INIT_E;
01914 
01915         if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
01916             ret = MP_READ_E;
01917 
01918         if (ret == 0)
01919             ret = sp_DhExp_3072(y, priv, privSz, &key->p, agree, agreeSz);
01920 
01921         mp_clear(y);
01922     #ifdef WOLFSSL_SMALL_STACK
01923     #ifndef WOLFSSL_SP_MATH
01924         XFREE(z, key->heap, DYNAMIC_TYPE_DH);
01925         XFREE(x, key->heap, DYNAMIC_TYPE_DH);
01926     #endif
01927         XFREE(y, key->heap, DYNAMIC_TYPE_DH);
01928     #endif
01929         return ret;
01930     }
01931 #endif
01932 #ifdef WOLFSSL_SP_4096
01933     if (mp_count_bits(&key->p) == 4096) {
01934         if (mp_init(y) != MP_OKAY)
01935             return MP_INIT_E;
01936 
01937         if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
01938             ret = MP_READ_E;
01939 
01940         if (ret == 0)
01941             ret = sp_DhExp_4096(y, priv, privSz, &key->p, agree, agreeSz);
01942 
01943         mp_clear(y);
01944     #ifdef WOLFSSL_SMALL_STACK
01945     #ifndef WOLFSSL_SP_MATH
01946         XFREE(z, key->heap, DYNAMIC_TYPE_DH);
01947         XFREE(x, key->heap, DYNAMIC_TYPE_DH);
01948     #endif
01949         XFREE(y, key->heap, DYNAMIC_TYPE_DH);
01950     #endif
01951         return ret;
01952     }
01953 #endif
01954 #endif
01955 
01956 #ifndef WOLFSSL_SP_MATH
01957     if (mp_init_multi(x, y, z, 0, 0, 0) != MP_OKAY) {
01958     #ifdef WOLFSSL_SMALL_STACK
01959         XFREE(z, key->heap, DYNAMIC_TYPE_DH);
01960         XFREE(x, key->heap, DYNAMIC_TYPE_DH);
01961         XFREE(y, key->heap, DYNAMIC_TYPE_DH);
01962     #endif
01963         return MP_INIT_E;
01964     }
01965 
01966     if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY)
01967         ret = MP_READ_E;
01968 
01969     if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
01970         ret = MP_READ_E;
01971 
01972     if (ret == 0 && mp_exptmod(y, x, &key->p, z) != MP_OKAY)
01973         ret = MP_EXPTMOD_E;
01974 
01975     /* make sure z is not one (SP800-56A, 5.7.1.1) */
01976     if (ret == 0 && (mp_cmp_d(z, 1) == MP_EQ))
01977         ret = MP_VAL;
01978 
01979     if (ret == 0 && mp_to_unsigned_bin(z, agree) != MP_OKAY)
01980         ret = MP_TO_E;
01981 
01982     if (ret == 0)
01983         *agreeSz = mp_unsigned_bin_size(z);
01984 
01985     mp_clear(z);
01986     mp_clear(y);
01987     mp_forcezero(x);
01988 #endif
01989 
01990 #ifdef WOLFSSL_SMALL_STACK
01991 #ifndef WOLFSSL_SP_MATH
01992     XFREE(z, key->heap, DYNAMIC_TYPE_DH);
01993     XFREE(x, key->heap, DYNAMIC_TYPE_DH);
01994 #endif
01995     XFREE(y, key->heap, DYNAMIC_TYPE_DH);
01996 #endif
01997 
01998     return ret;
01999 }
02000 
02001 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
02002 static int wc_DhAgree_Async(DhKey* key, byte* agree, word32* agreeSz,
02003     const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz)
02004 {
02005     int ret;
02006 
02007 #if defined(HAVE_INTEL_QA)
02008     word32 pBits;
02009 
02010     /* QAT DH sizes: 768, 1024, 1536, 2048, 3072 and 4096 bits */
02011     pBits = mp_unsigned_bin_size(&key->p) * 8;
02012     if (pBits == 768 ||  pBits == 1024 || pBits == 1536 ||
02013         pBits == 2048 || pBits == 3072 || pBits == 4096) {
02014         ret = wc_mp_to_bigint(&key->p, &key->p.raw);
02015         if (ret == MP_OKAY)
02016             ret = IntelQaDhAgree(&key->asyncDev, &key->p.raw,
02017                 agree, agreeSz, priv, privSz, otherPub, pubSz);
02018         return ret;
02019     }
02020 
02021 #elif defined(HAVE_CAVIUM)
02022     /* TODO: Not implemented - use software for now */
02023 
02024 #else /* WOLFSSL_ASYNC_CRYPT_TEST */
02025     if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_DH_AGREE)) {
02026         WC_ASYNC_TEST* testDev = &key->asyncDev.test;
02027         testDev->dhAgree.key = key;
02028         testDev->dhAgree.agree = agree;
02029         testDev->dhAgree.agreeSz = agreeSz;
02030         testDev->dhAgree.priv = priv;
02031         testDev->dhAgree.privSz = privSz;
02032         testDev->dhAgree.otherPub = otherPub;
02033         testDev->dhAgree.pubSz = pubSz;
02034         return WC_PENDING_E;
02035     }
02036 #endif
02037 
02038     /* otherwise use software DH */
02039     ret = wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub, pubSz);
02040 
02041     return ret;
02042 }
02043 #endif /* WOLFSSL_ASYNC_CRYPT */
02044 
02045 int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
02046             word32 privSz, const byte* otherPub, word32 pubSz)
02047 {
02048     int ret = 0;
02049 
02050     if (key == NULL || agree == NULL || agreeSz == NULL || priv == NULL ||
02051                                                             otherPub == NULL) {
02052         return BAD_FUNC_ARG;
02053     }
02054 
02055 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
02056     if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_DH) {
02057         ret = wc_DhAgree_Async(key, agree, agreeSz, priv, privSz, otherPub, pubSz);
02058     }
02059     else
02060 #endif
02061     {
02062         ret = wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub, pubSz);
02063     }
02064 
02065     return ret;
02066 }
02067 
02068 #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
02069 /* Sets private and public key in DhKey if both are available, otherwise sets
02070     either private or public key, depending on which is available.
02071     Returns WOLFSSL_SUCCESS if at least one of the keys was set. */
02072 WOLFSSL_LOCAL int wc_DhSetFullKeys(DhKey* key,const byte* priv_key,word32 privSz,
02073                                    const byte* pub_key, word32 pubSz)
02074 {
02075     byte havePriv = 0;
02076     byte havePub = 0;
02077     mp_int* keyPriv = NULL;
02078     mp_int* keyPub  = NULL;
02079 
02080     if (key == NULL) {
02081         return BAD_FUNC_ARG;
02082     }
02083 
02084     havePriv = ( (priv_key != NULL) && (privSz > 0) );
02085     havePub  = ( (pub_key  != NULL) && (pubSz  > 0) );
02086 
02087     if (!havePub && !havePriv) {
02088         WOLFSSL_MSG("No Public or Private Key to Set");
02089         return BAD_FUNC_ARG;
02090     }
02091     /* Set Private Key */
02092     if (havePriv == TRUE) {
02093         /* may have leading 0 */
02094         if (priv_key[0] == 0) {
02095             privSz--; priv_key++;
02096         }
02097         if (mp_init(&key->priv) != MP_OKAY)
02098             havePriv = FALSE;
02099     }
02100 
02101     if (havePriv == TRUE) {
02102         if (mp_read_unsigned_bin(&key->priv, priv_key, privSz) != MP_OKAY) {
02103             havePriv = FALSE;
02104         } else {
02105             keyPriv = &key->priv;
02106             WOLFSSL_MSG("DH Private Key Set.");
02107         }
02108     }
02109 
02110     /* Set Public Key */
02111     if (havePub == TRUE) {
02112         /* may have leading 0 */
02113         if (pub_key[0] == 0) {
02114             pubSz--; pub_key++;
02115         }
02116         if (mp_init(&key->pub) != MP_OKAY)
02117             havePub = FALSE;
02118     }
02119 
02120     if (havePub == TRUE) {
02121         if (mp_read_unsigned_bin(&key->pub, pub_key, pubSz) != MP_OKAY) {
02122             havePub = FALSE;
02123         } else {
02124             keyPub = &key->pub;
02125             WOLFSSL_MSG("DH Public Key Set.");
02126         }
02127     }
02128     /* Free Memory if error occured */
02129     if (havePriv == FALSE && keyPriv != NULL)
02130         mp_clear(keyPriv);
02131     if (havePub == FALSE && keyPub != NULL)
02132         mp_clear(keyPub);
02133 
02134     /* WOLFSSL_SUCCESS if private or public was set else WOLFSSL_FAILURE */
02135     return havePriv || havePub;
02136 }
02137 #endif
02138 
02139 static int _DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
02140                    word32 gSz, const byte* q, word32 qSz, int trusted,
02141                    WC_RNG* rng)
02142 {
02143     int ret = 0;
02144     mp_int* keyP = NULL;
02145     mp_int* keyG = NULL;
02146 
02147     if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0) {
02148         ret = BAD_FUNC_ARG;
02149     }
02150 
02151     if (ret == 0) {
02152         /* may have leading 0 */
02153         if (p[0] == 0) {
02154             pSz--; p++;
02155         }
02156 
02157         if (g[0] == 0) {
02158             gSz--; g++;
02159         }
02160 
02161         if (q != NULL) {
02162             if (q[0] == 0) {
02163                 qSz--; q++;
02164             }
02165         }
02166 
02167         if (mp_init(&key->p) != MP_OKAY)
02168             ret = MP_INIT_E;
02169     }
02170 
02171     if (ret == 0) {
02172         if (mp_read_unsigned_bin(&key->p, p, pSz) != MP_OKAY)
02173             ret = ASN_DH_KEY_E;
02174         else
02175             keyP = &key->p;
02176     }
02177 
02178     if (ret == 0 && !trusted) {
02179         int isPrime = 0;
02180         if (rng != NULL)
02181             ret = mp_prime_is_prime_ex(keyP, 8, &isPrime, rng);
02182         else
02183             ret = mp_prime_is_prime(keyP, 8, &isPrime);
02184 
02185         if (ret == 0 && isPrime == 0)
02186             ret = DH_CHECK_PUB_E;
02187     }
02188 
02189     if (ret == 0 && mp_init(&key->g) != MP_OKAY)
02190         ret = MP_INIT_E;
02191     if (ret == 0) {
02192         if (mp_read_unsigned_bin(&key->g, g, gSz) != MP_OKAY)
02193             ret = ASN_DH_KEY_E;
02194         else
02195             keyG = &key->g;
02196     }
02197 
02198     if (ret == 0 && q != NULL) {
02199         if (mp_init(&key->q) != MP_OKAY)
02200             ret = MP_INIT_E;
02201     }
02202     if (ret == 0 && q != NULL) {
02203         if (mp_read_unsigned_bin(&key->q, q, qSz) != MP_OKAY)
02204             ret = MP_INIT_E;
02205     }
02206 
02207     if (ret != 0 && key != NULL) {
02208         if (keyG)
02209             mp_clear(keyG);
02210         if (keyP)
02211             mp_clear(keyP);
02212     }
02213 
02214     return ret;
02215 }
02216 
02217 
02218 int wc_DhSetCheckKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
02219                    word32 gSz, const byte* q, word32 qSz, int trusted,
02220                    WC_RNG* rng)
02221 {
02222     return _DhSetKey(key, p, pSz, g, gSz, q, qSz, trusted, rng);
02223 }
02224 
02225 
02226 int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g,
02227                    word32 gSz, const byte* q, word32 qSz)
02228 {
02229     return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 1, NULL);
02230 }
02231 
02232 
02233 /* not in asn anymore since no actual asn types used */
02234 int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
02235                 word32 gSz)
02236 {
02237     return _DhSetKey(key, p, pSz, g, gSz, NULL, 0, 1, NULL);
02238 }
02239 
02240 
02241 #ifdef WOLFSSL_KEY_GEN
02242 
02243 /* modulus_size in bits */
02244 int wc_DhGenerateParams(WC_RNG *rng, int modSz, DhKey *dh)
02245 {
02246     mp_int  tmp, tmp2;
02247     int     groupSz = 0, bufSz = 0,
02248             primeCheckCount = 0,
02249             primeCheck = MP_NO,
02250             ret = 0;
02251     unsigned char *buf = NULL;
02252 
02253     if (rng == NULL || dh == NULL)
02254         ret = BAD_FUNC_ARG;
02255 
02256     /* set group size in bytes from modulus size
02257      * FIPS 186-4 defines valid values (1024, 160) (2048, 256) (3072, 256)
02258      */
02259     if (ret == 0) {
02260         switch (modSz) {
02261             case 1024:
02262                 groupSz = 20;
02263                 break;
02264             case 2048:
02265             case 3072:
02266                 groupSz = 32;
02267                 break;
02268             default:
02269                 ret = BAD_FUNC_ARG;
02270                 break;
02271         }
02272     }
02273 
02274     if (ret == 0) {
02275         /* modulus size in bytes */
02276         modSz /= WOLFSSL_BIT_SIZE;
02277         bufSz = modSz - groupSz;
02278 
02279         /* allocate ram */
02280         buf = (unsigned char *)XMALLOC(bufSz,
02281                                        dh->heap, DYNAMIC_TYPE_TMP_BUFFER);
02282         if (buf == NULL)
02283             ret = MEMORY_E;
02284     }
02285 
02286     /* make a random string that will be multiplied against q */
02287     if (ret == 0)
02288         ret = wc_RNG_GenerateBlock(rng, buf, bufSz);
02289 
02290     if (ret == 0) {
02291         /* force magnitude */
02292         buf[0] |= 0xC0;
02293         /* force even */
02294         buf[bufSz - 1] &= ~1;
02295 
02296         if (mp_init_multi(&tmp, &tmp2, &dh->p, &dh->q, &dh->g, 0)
02297                 != MP_OKAY) {
02298             ret = MP_INIT_E;
02299         }
02300     }
02301 
02302     if (ret == 0) {
02303         if (mp_read_unsigned_bin(&tmp2, buf, bufSz) != MP_OKAY)
02304             ret = MP_READ_E;
02305     }
02306 
02307     /* make our prime q */
02308     if (ret == 0) {
02309         if (mp_rand_prime(&dh->q, groupSz, rng, NULL) != MP_OKAY)
02310             ret = PRIME_GEN_E;
02311     }
02312 
02313     /* p = random * q */
02314     if (ret == 0) {
02315         if (mp_mul(&dh->q, &tmp2, &dh->p) != MP_OKAY)
02316             ret = MP_MUL_E;
02317     }
02318 
02319     /* p = random * q + 1, so q is a prime divisor of p-1 */
02320     if (ret == 0) {
02321         if (mp_add_d(&dh->p, 1, &dh->p) != MP_OKAY)
02322             ret = MP_ADD_E;
02323     }
02324 
02325     /* tmp = 2q  */
02326     if (ret == 0) {
02327         if (mp_add(&dh->q, &dh->q, &tmp) != MP_OKAY)
02328             ret = MP_ADD_E;
02329     }
02330 
02331     /* loop until p is prime */
02332     if (ret == 0) {
02333         do {
02334             if (mp_prime_is_prime_ex(&dh->p, 8, &primeCheck, rng) != MP_OKAY)
02335                 ret = PRIME_GEN_E;
02336 
02337             if (primeCheck != MP_YES) {
02338                 /* p += 2q */
02339                 if (mp_add(&tmp, &dh->p, &dh->p) != MP_OKAY)
02340                     ret = MP_ADD_E;
02341                 else
02342                     primeCheckCount++;
02343             }
02344         } while (ret == 0 && primeCheck == MP_NO);
02345     }
02346 
02347     /* tmp2 += (2*loop_check_prime)
02348      * to have p = (q * tmp2) + 1 prime
02349      */
02350     if ((ret == 0) && (primeCheckCount)) {
02351         if (mp_add_d(&tmp2, 2 * primeCheckCount, &tmp2) != MP_OKAY)
02352             ret = MP_ADD_E;
02353     }
02354 
02355     /* find a value g for which g^tmp2 != 1 */
02356     if ((ret == 0) && (mp_set(&dh->g, 1) != MP_OKAY))
02357         ret = MP_ZERO_E;
02358 
02359     if (ret == 0) {
02360         do {
02361             if (mp_add_d(&dh->g, 1, &dh->g) != MP_OKAY)
02362                 ret = MP_ADD_E;
02363             else if (mp_exptmod(&dh->g, &tmp2, &dh->p, &tmp) != MP_OKAY)
02364                 ret = MP_EXPTMOD_E;
02365         } while (ret == 0 && mp_cmp_d(&tmp, 1) == MP_EQ);
02366     }
02367 
02368     if (ret == 0) {
02369         /* at this point tmp generates a group of order q mod p */
02370         mp_exch(&tmp, &dh->g);
02371     }
02372 
02373     /* clear the parameters if there was an error */
02374     if ((ret != 0) && (dh != NULL)) {
02375         mp_clear(&dh->q);
02376         mp_clear(&dh->p);
02377         mp_clear(&dh->g);
02378     }
02379 
02380     if (buf != NULL) {
02381         ForceZero(buf, bufSz);
02382         if (dh != NULL) {
02383             XFREE(buf, dh->heap, DYNAMIC_TYPE_TMP_BUFFER);
02384         }
02385     }
02386     mp_clear(&tmp);
02387     mp_clear(&tmp2);
02388 
02389     return ret;
02390 }
02391 
02392 
02393 /* Export raw DH parameters from DhKey structure
02394  *
02395  * dh   - pointer to initialized DhKey structure
02396  * p    - output location for DH (p) parameter
02397  * pSz  - [IN/OUT] size of output buffer for p, size of p
02398  * q    - output location for DH (q) parameter
02399  * qSz  - [IN/OUT] size of output buffer for q, size of q
02400  * g    - output location for DH (g) parameter
02401  * gSz  - [IN/OUT] size of output buffer for g, size of g
02402  *
02403  * If p, q, and g pointers are all passed in as NULL, the function
02404  * will set pSz, qSz, and gSz to the required output buffer sizes for p,
02405  * q, and g. In this case, the function will return LENGTH_ONLY_E.
02406  *
02407  * returns 0 on success, negative upon failure
02408  */
02409 int wc_DhExportParamsRaw(DhKey* dh, byte* p, word32* pSz,
02410                          byte* q, word32* qSz, byte* g, word32* gSz)
02411 {
02412     int ret = 0;
02413     word32 pLen = 0, qLen = 0, gLen = 0;
02414 
02415     if (dh == NULL || pSz == NULL || qSz == NULL || gSz == NULL)
02416         ret = BAD_FUNC_ARG;
02417 
02418     /* get required output buffer sizes */
02419     if (ret == 0) {
02420         pLen = mp_unsigned_bin_size(&dh->p);
02421         qLen = mp_unsigned_bin_size(&dh->q);
02422         gLen = mp_unsigned_bin_size(&dh->g);
02423 
02424         /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */
02425         if (p == NULL && q == NULL && g == NULL) {
02426             *pSz = pLen;
02427             *qSz = qLen;
02428             *gSz = gLen;
02429             ret = LENGTH_ONLY_E;
02430         }
02431     }
02432 
02433     if (ret == 0) {
02434         if (p == NULL || q == NULL || g == NULL)
02435             ret = BAD_FUNC_ARG;
02436     }
02437 
02438     /* export p */
02439     if (ret == 0) {
02440         if (*pSz < pLen) {
02441             WOLFSSL_MSG("Output buffer for DH p parameter too small, "
02442                         "required size placed into pSz");
02443             *pSz = pLen;
02444             ret = BUFFER_E;
02445         }
02446     }
02447 
02448     if (ret == 0) {
02449         *pSz = pLen;
02450         if (mp_to_unsigned_bin(&dh->p, p) != MP_OKAY)
02451             ret = MP_TO_E;
02452     }
02453 
02454     /* export q */
02455     if (ret == 0) {
02456         if (*qSz < qLen) {
02457             WOLFSSL_MSG("Output buffer for DH q parameter too small, "
02458                         "required size placed into qSz");
02459             *qSz = qLen;
02460             ret = BUFFER_E;
02461         }
02462     }
02463 
02464     if (ret == 0) {
02465         *qSz = qLen;
02466         if (mp_to_unsigned_bin(&dh->q, q) != MP_OKAY)
02467             ret = MP_TO_E;
02468     }
02469 
02470     /* export g */
02471     if (ret == 0) {
02472         if (*gSz < gLen) {
02473             WOLFSSL_MSG("Output buffer for DH g parameter too small, "
02474                         "required size placed into gSz");
02475             *gSz = gLen;
02476             ret = BUFFER_E;
02477         }
02478     }
02479 
02480     if (ret == 0) {
02481         *gSz = gLen;
02482         if (mp_to_unsigned_bin(&dh->g, g) != MP_OKAY)
02483             ret = MP_TO_E;
02484     }
02485 
02486     return ret;
02487 }
02488 
02489 #endif /* WOLFSSL_KEY_GEN */
02490 
02491 #endif /* NO_DH */
02492