Xuyi Wang / wolfcrypt

Dependents:   OS

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