/* dh.c * * Copyright (C) 2006-2022 wolfSSL Inc. * * This file is part of wolfSSL. * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * wolfSSL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ #ifdef HAVE_CONFIG_H #include #endif #include #ifndef NO_DH #if defined(HAVE_FIPS) && \ defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ #define FIPS_NO_WRAPPERS #ifdef USE_WINDOWS_API #pragma code_seg(".fipsA$m") #pragma const_seg(".fipsB$m") #endif #endif #include #include #include #ifdef WOLFSSL_HAVE_SP_DH #include #endif #ifdef NO_INLINE #include #else #define WOLFSSL_MISC_INCLUDED #include #endif /* Possible DH enable options: * NO_RSA: Overall control of DH default: on (not defined) * WOLFSSL_OLD_PRIME_CHECK: Disables the new prime number check. It does not directly effect this file, but it does speed up DH removing the testing. It is not recommended to disable the prime checking. default: off * WOLFSSL_VALIDATE_DH_KEYGEN: Enable DH key gen consistency checking * (on for FIPS 140-3 or later) default: off */ #if !defined(USER_MATH_LIB) && !defined(WOLFSSL_DH_CONST) #include #define XPOW(x,y) pow((x),(y)) #define XLOG(x) log((x)) #else /* user's own math lib */ #endif #ifdef HAVE_FFDHE_2048 static const byte dh_ffdhe2048_p[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, 0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; static const byte dh_ffdhe2048_g[] = { 0x02 }; #ifdef HAVE_FFDHE_Q static const byte dh_ffdhe2048_q[] = { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D, 0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78, 0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A, 0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD, 0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C, 0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC, 0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD, 0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0, 0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68, 0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79, 0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A, 0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB, 0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39, 0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A, 0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD, 0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0, 0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD, 0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34, 0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA, 0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C, 0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8, 0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76, 0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0, 0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF, 0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1, 0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9, 0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02, 0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9, 0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD, 0x44, 0x35, 0xA1, 0x1C, 0x30, 0x94, 0x2E, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; #endif /* HAVE_FFDHE_Q */ #ifdef HAVE_PUBLIC_FFDHE const DhParams* wc_Dh_ffdhe2048_Get(void) { static const DhParams ffdhe2048 = { #ifdef HAVE_FFDHE_Q dh_ffdhe2048_q, sizeof(dh_ffdhe2048_q), #endif /* HAVE_FFDHE_Q */ dh_ffdhe2048_p, sizeof(dh_ffdhe2048_p), dh_ffdhe2048_g, sizeof(dh_ffdhe2048_g) }; return &ffdhe2048; } #endif #endif #ifdef HAVE_FFDHE_3072 static const byte dh_ffdhe3072_p[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0xC6, 0x2E, 0x37, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; static const byte dh_ffdhe3072_g[] = { 0x02 }; #ifdef HAVE_FFDHE_Q static const byte dh_ffdhe3072_q[] = { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D, 0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78, 0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A, 0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD, 0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C, 0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC, 0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD, 0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0, 0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68, 0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79, 0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A, 0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB, 0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39, 0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A, 0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD, 0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0, 0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD, 0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34, 0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA, 0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C, 0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8, 0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76, 0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0, 0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF, 0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1, 0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9, 0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02, 0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9, 0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD, 0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE, 0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD, 0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C, 0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83, 0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7, 0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E, 0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38, 0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2, 0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9, 0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF, 0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F, 0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06, 0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D, 0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27, 0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7, 0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE, 0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x63, 0x17, 0x1B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; #endif /* HAVE_FFDHE_Q */ #ifdef HAVE_PUBLIC_FFDHE const DhParams* wc_Dh_ffdhe3072_Get(void) { static const DhParams ffdhe3072 = { #ifdef HAVE_FFDHE_Q dh_ffdhe3072_q, sizeof(dh_ffdhe3072_q), #endif /* HAVE_FFDHE_Q */ dh_ffdhe3072_p, sizeof(dh_ffdhe3072_p), dh_ffdhe3072_g, sizeof(dh_ffdhe3072_g) }; return &ffdhe3072; } #endif #endif #ifdef HAVE_FFDHE_4096 static const byte dh_ffdhe4096_p[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x65, 0x5F, 0x6A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; static const byte dh_ffdhe4096_g[] = { 0x02 }; #ifdef HAVE_FFDHE_Q static const byte dh_ffdhe4096_q[] = { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D, 0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78, 0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A, 0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD, 0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C, 0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC, 0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD, 0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0, 0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68, 0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79, 0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A, 0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB, 0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39, 0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A, 0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD, 0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0, 0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD, 0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34, 0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA, 0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C, 0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8, 0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76, 0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0, 0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF, 0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1, 0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9, 0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02, 0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9, 0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD, 0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE, 0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD, 0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C, 0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83, 0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7, 0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E, 0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38, 0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2, 0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9, 0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF, 0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F, 0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06, 0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D, 0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27, 0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7, 0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE, 0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78, 0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D, 0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB, 0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C, 0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02, 0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D, 0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5, 0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19, 0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62, 0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C, 0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD, 0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E, 0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66, 0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7, 0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35, 0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70, 0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x32, 0xAF, 0xB5, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; #endif /* HAVE_FFDHE_Q */ #ifdef HAVE_PUBLIC_FFDHE const DhParams* wc_Dh_ffdhe4096_Get(void) { static const DhParams ffdhe4096 = { #ifdef HAVE_FFDHE_Q dh_ffdhe4096_q, sizeof(dh_ffdhe4096_q), #endif /* HAVE_FFDHE_Q */ dh_ffdhe4096_p, sizeof(dh_ffdhe4096_p), dh_ffdhe4096_g, sizeof(dh_ffdhe4096_g) }; return &ffdhe4096; } #endif #endif #ifdef HAVE_FFDHE_6144 static const byte dh_ffdhe6144_p[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, 0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, 0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, 0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, 0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, 0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, 0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, 0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, 0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, 0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, 0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, 0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, 0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, 0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, 0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, 0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, 0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, 0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, 0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, 0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, 0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, 0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, 0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, 0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, 0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, 0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, 0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, 0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, 0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, 0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, 0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, 0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, 0xA4, 0x0E, 0x32, 0x9C, 0xD0, 0xE4, 0x0E, 0x65, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; static const byte dh_ffdhe6144_g[] = { 0x02 }; #ifdef HAVE_FFDHE_Q static const byte dh_ffdhe6144_q[] = { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D, 0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78, 0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A, 0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD, 0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C, 0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC, 0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD, 0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0, 0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68, 0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79, 0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A, 0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB, 0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39, 0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A, 0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD, 0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0, 0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD, 0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34, 0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA, 0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C, 0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8, 0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76, 0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0, 0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF, 0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1, 0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9, 0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02, 0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9, 0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD, 0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE, 0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD, 0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C, 0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83, 0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7, 0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E, 0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38, 0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2, 0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9, 0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF, 0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F, 0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06, 0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D, 0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27, 0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7, 0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE, 0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78, 0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D, 0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB, 0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C, 0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02, 0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D, 0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5, 0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19, 0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62, 0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C, 0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD, 0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E, 0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66, 0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7, 0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35, 0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70, 0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x06, 0xEC, 0x81, 0x05, 0xFE, 0xB2, 0x5B, 0x22, 0x81, 0xB6, 0x3D, 0x27, 0x33, 0xBE, 0x96, 0x1C, 0x29, 0x95, 0x1D, 0x11, 0xDD, 0x22, 0x21, 0x65, 0x7A, 0x9F, 0x53, 0x1D, 0xDA, 0x2A, 0x19, 0x4D, 0xBB, 0x12, 0x64, 0x48, 0xBD, 0xEE, 0xB2, 0x58, 0xE0, 0x7E, 0xA6, 0x59, 0xC7, 0x46, 0x19, 0xA6, 0x38, 0x0E, 0x1D, 0x66, 0xD6, 0x83, 0x2B, 0xFE, 0x67, 0xF6, 0x38, 0xCD, 0x8F, 0xAE, 0x1F, 0x27, 0x23, 0x02, 0x0F, 0x9C, 0x40, 0xA3, 0xFD, 0xA6, 0x7E, 0xDA, 0x3B, 0xD2, 0x92, 0x38, 0xFB, 0xD4, 0xD4, 0xB4, 0x88, 0x5C, 0x2A, 0x99, 0x17, 0x6D, 0xB1, 0xA0, 0x6C, 0x50, 0x07, 0x78, 0x49, 0x1A, 0x82, 0x88, 0xF1, 0x85, 0x5F, 0x60, 0xFF, 0xFC, 0xF1, 0xD1, 0x37, 0x3F, 0xD9, 0x4F, 0xC6, 0x0C, 0x18, 0x11, 0xE1, 0xAC, 0x3F, 0x1C, 0x6D, 0x00, 0x3B, 0xEC, 0xDA, 0x3B, 0x1F, 0x27, 0x25, 0xCA, 0x59, 0x5D, 0xE0, 0xCA, 0x63, 0x32, 0x8F, 0x3B, 0xE5, 0x7C, 0xC9, 0x77, 0x55, 0x60, 0x11, 0x95, 0x14, 0x0D, 0xFB, 0x59, 0xD3, 0x9C, 0xE0, 0x91, 0x30, 0x8B, 0x41, 0x05, 0x74, 0x6D, 0xAC, 0x23, 0xD3, 0x3E, 0x5F, 0x7C, 0xE4, 0x84, 0x8D, 0xA3, 0x16, 0xA9, 0xC6, 0x6B, 0x95, 0x81, 0xBA, 0x35, 0x73, 0xBF, 0xAF, 0x31, 0x14, 0x96, 0x18, 0x8A, 0xB1, 0x54, 0x23, 0x28, 0x2E, 0xE4, 0x16, 0xDC, 0x2A, 0x19, 0xC5, 0x72, 0x4F, 0xA9, 0x1A, 0xE4, 0xAD, 0xC8, 0x8B, 0xC6, 0x67, 0x96, 0xEA, 0xE5, 0x67, 0x7A, 0x01, 0xF6, 0x4E, 0x8C, 0x08, 0x63, 0x13, 0x95, 0x82, 0x2D, 0x9D, 0xB8, 0xFC, 0xEE, 0x35, 0xC0, 0x6B, 0x1F, 0xEE, 0xA5, 0x47, 0x4D, 0x6D, 0x8F, 0x34, 0xB1, 0x53, 0x4A, 0x93, 0x6A, 0x18, 0xB0, 0xE0, 0xD2, 0x0E, 0xAB, 0x86, 0xBC, 0x9C, 0x6D, 0x6A, 0x52, 0x07, 0x19, 0x4E, 0x68, 0x72, 0x07, 0x32, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; #endif /* HAVE_FFDHE_Q */ #ifdef HAVE_PUBLIC_FFDHE const DhParams* wc_Dh_ffdhe6144_Get(void) { static const DhParams ffdhe6144 = { #ifdef HAVE_FFDHE_Q dh_ffdhe6144_q, sizeof(dh_ffdhe6144_q), #endif /* HAVE_FFDHE_Q */ dh_ffdhe6144_p, sizeof(dh_ffdhe6144_p), dh_ffdhe6144_g, sizeof(dh_ffdhe6144_g) }; return &ffdhe6144; } #endif #endif #ifdef HAVE_FFDHE_8192 static const byte dh_ffdhe8192_p[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, 0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1, 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95, 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB, 0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, 0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, 0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A, 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61, 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0, 0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, 0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, 0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77, 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72, 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35, 0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, 0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, 0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB, 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68, 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4, 0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, 0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, 0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC, 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61, 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF, 0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, 0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, 0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05, 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2, 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA, 0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC, 0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B, 0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38, 0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07, 0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE, 0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C, 0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70, 0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44, 0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3, 0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF, 0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E, 0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D, 0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA, 0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E, 0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF, 0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C, 0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1, 0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB, 0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6, 0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18, 0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04, 0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A, 0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A, 0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32, 0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4, 0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38, 0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A, 0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C, 0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC, 0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF, 0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B, 0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1, 0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02, 0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A, 0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A, 0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6, 0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8, 0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C, 0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A, 0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71, 0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F, 0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77, 0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10, 0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8, 0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3, 0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E, 0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3, 0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4, 0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1, 0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92, 0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6, 0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82, 0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE, 0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C, 0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E, 0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46, 0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A, 0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17, 0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03, 0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04, 0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6, 0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69, 0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1, 0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4, 0xA4, 0x0E, 0x32, 0x9C, 0xCF, 0xF4, 0x6A, 0xAA, 0x36, 0xAD, 0x00, 0x4C, 0xF6, 0x00, 0xC8, 0x38, 0x1E, 0x42, 0x5A, 0x31, 0xD9, 0x51, 0xAE, 0x64, 0xFD, 0xB2, 0x3F, 0xCE, 0xC9, 0x50, 0x9D, 0x43, 0x68, 0x7F, 0xEB, 0x69, 0xED, 0xD1, 0xCC, 0x5E, 0x0B, 0x8C, 0xC3, 0xBD, 0xF6, 0x4B, 0x10, 0xEF, 0x86, 0xB6, 0x31, 0x42, 0xA3, 0xAB, 0x88, 0x29, 0x55, 0x5B, 0x2F, 0x74, 0x7C, 0x93, 0x26, 0x65, 0xCB, 0x2C, 0x0F, 0x1C, 0xC0, 0x1B, 0xD7, 0x02, 0x29, 0x38, 0x88, 0x39, 0xD2, 0xAF, 0x05, 0xE4, 0x54, 0x50, 0x4A, 0xC7, 0x8B, 0x75, 0x82, 0x82, 0x28, 0x46, 0xC0, 0xBA, 0x35, 0xC3, 0x5F, 0x5C, 0x59, 0x16, 0x0C, 0xC0, 0x46, 0xFD, 0x82, 0x51, 0x54, 0x1F, 0xC6, 0x8C, 0x9C, 0x86, 0xB0, 0x22, 0xBB, 0x70, 0x99, 0x87, 0x6A, 0x46, 0x0E, 0x74, 0x51, 0xA8, 0xA9, 0x31, 0x09, 0x70, 0x3F, 0xEE, 0x1C, 0x21, 0x7E, 0x6C, 0x38, 0x26, 0xE5, 0x2C, 0x51, 0xAA, 0x69, 0x1E, 0x0E, 0x42, 0x3C, 0xFC, 0x99, 0xE9, 0xE3, 0x16, 0x50, 0xC1, 0x21, 0x7B, 0x62, 0x48, 0x16, 0xCD, 0xAD, 0x9A, 0x95, 0xF9, 0xD5, 0xB8, 0x01, 0x94, 0x88, 0xD9, 0xC0, 0xA0, 0xA1, 0xFE, 0x30, 0x75, 0xA5, 0x77, 0xE2, 0x31, 0x83, 0xF8, 0x1D, 0x4A, 0x3F, 0x2F, 0xA4, 0x57, 0x1E, 0xFC, 0x8C, 0xE0, 0xBA, 0x8A, 0x4F, 0xE8, 0xB6, 0x85, 0x5D, 0xFE, 0x72, 0xB0, 0xA6, 0x6E, 0xDE, 0xD2, 0xFB, 0xAB, 0xFB, 0xE5, 0x8A, 0x30, 0xFA, 0xFA, 0xBE, 0x1C, 0x5D, 0x71, 0xA8, 0x7E, 0x2F, 0x74, 0x1E, 0xF8, 0xC1, 0xFE, 0x86, 0xFE, 0xA6, 0xBB, 0xFD, 0xE5, 0x30, 0x67, 0x7F, 0x0D, 0x97, 0xD1, 0x1D, 0x49, 0xF7, 0xA8, 0x44, 0x3D, 0x08, 0x22, 0xE5, 0x06, 0xA9, 0xF4, 0x61, 0x4E, 0x01, 0x1E, 0x2A, 0x94, 0x83, 0x8F, 0xF8, 0x8C, 0xD6, 0x8C, 0x8B, 0xB7, 0xC5, 0xC6, 0x42, 0x4C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; static const byte dh_ffdhe8192_g[] = { 0x02 }; #ifdef HAVE_FFDHE_Q static const byte dh_ffdhe8192_q[] = { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D, 0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78, 0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A, 0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD, 0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C, 0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC, 0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD, 0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0, 0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68, 0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79, 0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A, 0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB, 0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39, 0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A, 0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD, 0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0, 0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD, 0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34, 0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA, 0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C, 0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8, 0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76, 0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0, 0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF, 0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1, 0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9, 0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02, 0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9, 0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD, 0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE, 0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD, 0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C, 0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83, 0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7, 0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E, 0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38, 0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2, 0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9, 0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF, 0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F, 0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06, 0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D, 0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27, 0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7, 0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE, 0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78, 0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D, 0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB, 0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C, 0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02, 0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D, 0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5, 0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19, 0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62, 0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C, 0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD, 0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E, 0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66, 0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7, 0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35, 0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70, 0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x06, 0xEC, 0x81, 0x05, 0xFE, 0xB2, 0x5B, 0x22, 0x81, 0xB6, 0x3D, 0x27, 0x33, 0xBE, 0x96, 0x1C, 0x29, 0x95, 0x1D, 0x11, 0xDD, 0x22, 0x21, 0x65, 0x7A, 0x9F, 0x53, 0x1D, 0xDA, 0x2A, 0x19, 0x4D, 0xBB, 0x12, 0x64, 0x48, 0xBD, 0xEE, 0xB2, 0x58, 0xE0, 0x7E, 0xA6, 0x59, 0xC7, 0x46, 0x19, 0xA6, 0x38, 0x0E, 0x1D, 0x66, 0xD6, 0x83, 0x2B, 0xFE, 0x67, 0xF6, 0x38, 0xCD, 0x8F, 0xAE, 0x1F, 0x27, 0x23, 0x02, 0x0F, 0x9C, 0x40, 0xA3, 0xFD, 0xA6, 0x7E, 0xDA, 0x3B, 0xD2, 0x92, 0x38, 0xFB, 0xD4, 0xD4, 0xB4, 0x88, 0x5C, 0x2A, 0x99, 0x17, 0x6D, 0xB1, 0xA0, 0x6C, 0x50, 0x07, 0x78, 0x49, 0x1A, 0x82, 0x88, 0xF1, 0x85, 0x5F, 0x60, 0xFF, 0xFC, 0xF1, 0xD1, 0x37, 0x3F, 0xD9, 0x4F, 0xC6, 0x0C, 0x18, 0x11, 0xE1, 0xAC, 0x3F, 0x1C, 0x6D, 0x00, 0x3B, 0xEC, 0xDA, 0x3B, 0x1F, 0x27, 0x25, 0xCA, 0x59, 0x5D, 0xE0, 0xCA, 0x63, 0x32, 0x8F, 0x3B, 0xE5, 0x7C, 0xC9, 0x77, 0x55, 0x60, 0x11, 0x95, 0x14, 0x0D, 0xFB, 0x59, 0xD3, 0x9C, 0xE0, 0x91, 0x30, 0x8B, 0x41, 0x05, 0x74, 0x6D, 0xAC, 0x23, 0xD3, 0x3E, 0x5F, 0x7C, 0xE4, 0x84, 0x8D, 0xA3, 0x16, 0xA9, 0xC6, 0x6B, 0x95, 0x81, 0xBA, 0x35, 0x73, 0xBF, 0xAF, 0x31, 0x14, 0x96, 0x18, 0x8A, 0xB1, 0x54, 0x23, 0x28, 0x2E, 0xE4, 0x16, 0xDC, 0x2A, 0x19, 0xC5, 0x72, 0x4F, 0xA9, 0x1A, 0xE4, 0xAD, 0xC8, 0x8B, 0xC6, 0x67, 0x96, 0xEA, 0xE5, 0x67, 0x7A, 0x01, 0xF6, 0x4E, 0x8C, 0x08, 0x63, 0x13, 0x95, 0x82, 0x2D, 0x9D, 0xB8, 0xFC, 0xEE, 0x35, 0xC0, 0x6B, 0x1F, 0xEE, 0xA5, 0x47, 0x4D, 0x6D, 0x8F, 0x34, 0xB1, 0x53, 0x4A, 0x93, 0x6A, 0x18, 0xB0, 0xE0, 0xD2, 0x0E, 0xAB, 0x86, 0xBC, 0x9C, 0x6D, 0x6A, 0x52, 0x07, 0x19, 0x4E, 0x67, 0xFA, 0x35, 0x55, 0x1B, 0x56, 0x80, 0x26, 0x7B, 0x00, 0x64, 0x1C, 0x0F, 0x21, 0x2D, 0x18, 0xEC, 0xA8, 0xD7, 0x32, 0x7E, 0xD9, 0x1F, 0xE7, 0x64, 0xA8, 0x4E, 0xA1, 0xB4, 0x3F, 0xF5, 0xB4, 0xF6, 0xE8, 0xE6, 0x2F, 0x05, 0xC6, 0x61, 0xDE, 0xFB, 0x25, 0x88, 0x77, 0xC3, 0x5B, 0x18, 0xA1, 0x51, 0xD5, 0xC4, 0x14, 0xAA, 0xAD, 0x97, 0xBA, 0x3E, 0x49, 0x93, 0x32, 0xE5, 0x96, 0x07, 0x8E, 0x60, 0x0D, 0xEB, 0x81, 0x14, 0x9C, 0x44, 0x1C, 0xE9, 0x57, 0x82, 0xF2, 0x2A, 0x28, 0x25, 0x63, 0xC5, 0xBA, 0xC1, 0x41, 0x14, 0x23, 0x60, 0x5D, 0x1A, 0xE1, 0xAF, 0xAE, 0x2C, 0x8B, 0x06, 0x60, 0x23, 0x7E, 0xC1, 0x28, 0xAA, 0x0F, 0xE3, 0x46, 0x4E, 0x43, 0x58, 0x11, 0x5D, 0xB8, 0x4C, 0xC3, 0xB5, 0x23, 0x07, 0x3A, 0x28, 0xD4, 0x54, 0x98, 0x84, 0xB8, 0x1F, 0xF7, 0x0E, 0x10, 0xBF, 0x36, 0x1C, 0x13, 0x72, 0x96, 0x28, 0xD5, 0x34, 0x8F, 0x07, 0x21, 0x1E, 0x7E, 0x4C, 0xF4, 0xF1, 0x8B, 0x28, 0x60, 0x90, 0xBD, 0xB1, 0x24, 0x0B, 0x66, 0xD6, 0xCD, 0x4A, 0xFC, 0xEA, 0xDC, 0x00, 0xCA, 0x44, 0x6C, 0xE0, 0x50, 0x50, 0xFF, 0x18, 0x3A, 0xD2, 0xBB, 0xF1, 0x18, 0xC1, 0xFC, 0x0E, 0xA5, 0x1F, 0x97, 0xD2, 0x2B, 0x8F, 0x7E, 0x46, 0x70, 0x5D, 0x45, 0x27, 0xF4, 0x5B, 0x42, 0xAE, 0xFF, 0x39, 0x58, 0x53, 0x37, 0x6F, 0x69, 0x7D, 0xD5, 0xFD, 0xF2, 0xC5, 0x18, 0x7D, 0x7D, 0x5F, 0x0E, 0x2E, 0xB8, 0xD4, 0x3F, 0x17, 0xBA, 0x0F, 0x7C, 0x60, 0xFF, 0x43, 0x7F, 0x53, 0x5D, 0xFE, 0xF2, 0x98, 0x33, 0xBF, 0x86, 0xCB, 0xE8, 0x8E, 0xA4, 0xFB, 0xD4, 0x22, 0x1E, 0x84, 0x11, 0x72, 0x83, 0x54, 0xFA, 0x30, 0xA7, 0x00, 0x8F, 0x15, 0x4A, 0x41, 0xC7, 0xFC, 0x46, 0x6B, 0x46, 0x45, 0xDB, 0xE2, 0xE3, 0x21, 0x26, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; #endif /* HAVE_FFDHE_Q */ #ifdef HAVE_PUBLIC_FFDHE const DhParams* wc_Dh_ffdhe8192_Get(void) { static const DhParams ffdhe8192 = { #ifdef HAVE_FFDHE_Q dh_ffdhe8192_q, sizeof(dh_ffdhe8192_q), #endif /* HAVE_FFDHE_Q */ dh_ffdhe8192_p, sizeof(dh_ffdhe8192_p), dh_ffdhe8192_g, sizeof(dh_ffdhe8192_g) }; return &ffdhe8192; } #endif #endif int wc_InitDhKey_ex(DhKey* key, void* heap, int devId) { int ret = 0; if (key == NULL) return BAD_FUNC_ARG; key->heap = heap; /* for XMALLOC/XFREE in future */ key->trustedGroup = 0; #ifdef WOLFSSL_DH_EXTRA if (mp_init_multi(&key->p, &key->g, &key->q, &key->pub, &key->priv, NULL) != MP_OKAY) #else if (mp_init_multi(&key->p, &key->g, &key->q, NULL, NULL, NULL) != MP_OKAY) #endif return MEMORY_E; #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH) /* handle as async */ ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_DH, key->heap, devId); #else (void)devId; #endif key->trustedGroup = 0; #ifdef WOLFSSL_KCAPI_DH key->handle = NULL; #endif return ret; } int wc_InitDhKey(DhKey* key) { return wc_InitDhKey_ex(key, NULL, INVALID_DEVID); } int wc_FreeDhKey(DhKey* key) { if (key) { mp_clear(&key->p); mp_clear(&key->g); mp_clear(&key->q); #ifdef WOLFSSL_DH_EXTRA mp_clear(&key->pub); mp_forcezero(&key->priv); #endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH) wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_DH); #endif #ifdef WOLFSSL_KCAPI_DH KcapiDh_Free(key); #endif } return 0; } static int _ffc_validate_public_key(DhKey* key, const byte* pub, word32 pubSz, const byte* prime, word32 primeSz, int partial); #if FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_DH_KEYGEN) static int _ffc_pairwise_consistency_test(DhKey* key, const byte* pub, word32 pubSz, const byte* priv, word32 privSz); #endif #ifndef WOLFSSL_KCAPI_DH #ifndef WC_NO_RNG /* if defined to not use floating point values do not compile in */ #ifndef WOLFSSL_DH_CONST static word32 DiscreteLogWorkFactor(word32 n) { /* assuming discrete log takes about the same time as factoring */ if (n < 5) return 0; else return (word32)(2.4 * XPOW((double)n, 1.0/3.0) * XPOW(XLOG((double)n), 2.0/3.0) - 5); } #endif /* WOLFSSL_DH_CONST*/ /* if not using fixed points use DiscreteLogWorkFactor function for unusual size otherwise round up on size needed */ #ifndef WOLFSSL_DH_CONST #define WOLFSSL_DH_ROUND(x) #else #define WOLFSSL_DH_ROUND(x) \ do { \ if (x % 128) { \ x &= 0xffffff80;\ x += 128; \ } \ } \ while (0) #endif #ifndef WOLFSSL_NO_DH186 /* validate that (L,N) match allowed sizes from SP 800-56A, Section 5.5.1.1. * modLen - represents L, the size of p in bits * divLen - represents N, the size of q in bits * return 0 on success, -1 on error */ static int CheckDhLN(int modLen, int divLen) { int ret = -1; switch (modLen) { /* FA */ case 1024: if (divLen == 160) ret = 0; break; /* FB, FC */ case 2048: if (divLen == 224 || divLen == 256) ret = 0; break; default: break; } return ret; } /* Create DH private key * * Based on NIST SP 800-56Ar3 * "5.6.1.1.3 Key Pair Generation Using Extra Random Bits" * * dh - pointer to initialized DhKey structure, needs to have dh->q * rng - pointer to initialized WC_RNG structure * priv - output location for generated private key * privSz - IN/OUT, size of priv buffer, size of generated private key * * return 0 on success, negative on error */ static int GeneratePrivateDh186(DhKey* key, WC_RNG* rng, byte* priv, word32* privSz) { byte* cBuf; int qSz, pSz, cSz, err; #ifdef WOLFSSL_SMALL_STACK mp_int* tmpQ = NULL; mp_int* tmpX = NULL; #else mp_int tmpQ[1], tmpX[1]; #endif /* Parameters validated in calling functions. */ if (mp_iszero(&key->q) == MP_YES) { WOLFSSL_MSG("DH q parameter needed for FIPS 186-4 key generation"); return BAD_FUNC_ARG; } qSz = mp_unsigned_bin_size(&key->q); pSz = mp_unsigned_bin_size(&key->p); /* verify (L,N) pair bit lengths */ /* Trusted primes don't need to be checked. */ if (!key->trustedGroup && CheckDhLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0) { WOLFSSL_MSG("DH param sizes do not match SP 800-56A requirements"); return BAD_FUNC_ARG; } /* generate extra 64 bits so that bias from mod function is negligible */ cSz = *privSz + (64 / WOLFSSL_BIT_SIZE); cBuf = (byte*)XMALLOC(cSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER); if (cBuf == NULL) { return MEMORY_E; } #ifdef WOLFSSL_SMALL_STACK tmpQ = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (tmpQ == NULL) { XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; } tmpX = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (tmpX == NULL) { XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH); return MEMORY_E; } #endif if ((err = mp_init_multi(tmpX, tmpQ, NULL, NULL, NULL, NULL)) != MP_OKAY) { XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER); #ifdef WOLFSSL_SMALL_STACK XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH); XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH); #endif return err; } #ifdef WOLFSSL_CHECK_MEM_ZERO wc_MemZero_Add("GeneratePrivateDh186 cBuf", cBuf, cSz); mp_memzero_add("GeneratePrivateDh186 tmpX", tmpX); #endif do { /* generate N+64 bits (c) from RBG into tmpX, making sure positive. * Hash_DRBG uses SHA-256 which matches maximum * requested_security_strength of (L,N) */ err = wc_RNG_GenerateBlock(rng, cBuf, cSz); if (err == MP_OKAY) err = mp_read_unsigned_bin(tmpX, cBuf, cSz); if (err != MP_OKAY) { mp_clear(tmpX); mp_clear(tmpQ); XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER); #ifdef WOLFSSL_SMALL_STACK XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH); XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH); #endif return err; } } while (mp_cmp_d(tmpX, 1) != MP_GT); ForceZero(cBuf, cSz); XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER); /* tmpQ: M = min(2^N,q) - 1 */ if (err == MP_OKAY) err = mp_2expt(tmpQ, *privSz * 8); if (err == MP_OKAY) { if (mp_cmp(tmpQ, &key->q) == MP_GT) { err = mp_copy(&key->q, tmpQ); } } if (err == MP_OKAY) err = mp_sub_d(tmpQ, 1, tmpQ); /* x = c mod (M), tmpX holds c */ if (err == MP_OKAY) err = mp_mod(tmpX, tmpQ, tmpX); /* x = c mod (M) + 1 */ if (err == MP_OKAY) err = mp_add_d(tmpX, 1, tmpX); /* copy tmpX into priv */ if (err == MP_OKAY) { pSz = mp_unsigned_bin_size(tmpX); if (pSz > (int)*privSz) { WOLFSSL_MSG("DH private key output buffer too small"); err = BAD_FUNC_ARG; } else { *privSz = pSz; err = mp_to_unsigned_bin(tmpX, priv); } } mp_forcezero(tmpX); mp_clear(tmpQ); #ifdef WOLFSSL_SMALL_STACK XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH); XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH); #elif defined(WOLFSSL_CHECK_MEM_ZERO) mp_memzero_check(tmpX); #endif return err; } #endif /* WOLFSSL_NO_DH186 */ #endif /* !WC_NO_RNG */ static int GeneratePrivateDh(DhKey* key, WC_RNG* rng, byte* priv, word32* privSz) { #ifndef WC_NO_RNG int ret = 0; word32 sz = 0; if (mp_iseven(&key->p) == MP_YES) { ret = MP_VAL; } else #ifndef WOLFSSL_NO_DH186 if (mp_iszero(&key->q) == MP_NO) { /* q param available, use NIST SP 800-56Ar3, "5.6.1.1.3 Key Pair * Generation Using Extra Random Bits" */ ret = GeneratePrivateDh186(key, rng, priv, privSz); } else #endif { sz = mp_unsigned_bin_size(&key->p); /* Table of predetermined values from the operation 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) / WOLFSSL_BIT_SIZE + 1 Sizes in table checked against RFC 3526 */ WOLFSSL_DH_ROUND(sz); /* if using fixed points only, then round up */ switch (sz) { case 128: sz = 21; break; case 256: sz = 29; break; case 384: sz = 34; break; case 512: sz = 39; break; case 640: sz = 42; break; case 768: sz = 46; break; case 896: sz = 49; break; case 1024: sz = 52; break; default: #ifndef WOLFSSL_DH_CONST /* if using floating points and size of p is not in table */ sz = min(sz, 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) / WOLFSSL_BIT_SIZE + 1); break; #else return BAD_FUNC_ARG; #endif } if (sz > *privSz) ret = WC_KEY_SIZE_E; if (ret == 0) ret = wc_RNG_GenerateBlock(rng, priv, sz); if (ret == 0) { priv[0] |= 0x0C; *privSz = sz; } } return ret; #else (void)key; (void)rng; (void)priv; (void)privSz; return NOT_COMPILED_IN; #endif /* WC_NO_RNG */ } static int GeneratePublicDh(DhKey* key, byte* priv, word32 privSz, byte* pub, word32* pubSz) { int ret = 0; #ifndef WOLFSSL_SP_MATH word32 binSz = 0; #ifdef WOLFSSL_SMALL_STACK mp_int* x; mp_int* y; #else mp_int x[1]; mp_int y[1]; #endif #endif #ifdef WOLFSSL_HAVE_SP_DH #ifndef WOLFSSL_SP_NO_2048 if (mp_count_bits(&key->p) == 2048) return sp_DhExp_2048(&key->g, priv, privSz, &key->p, pub, pubSz); #endif #ifndef WOLFSSL_SP_NO_3072 if (mp_count_bits(&key->p) == 3072) return sp_DhExp_3072(&key->g, priv, privSz, &key->p, pub, pubSz); #endif #ifdef WOLFSSL_SP_4096 if (mp_count_bits(&key->p) == 4096) return sp_DhExp_4096(&key->g, priv, privSz, &key->p, pub, pubSz); #endif #endif #if !defined(WOLFSSL_SP_MATH) #ifdef WOLFSSL_SMALL_STACK x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (x == NULL) return MEMORY_E; y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (y == NULL) { XFREE(x, key->heap, DYNAMIC_TYPE_DH); return MEMORY_E; } #endif if (mp_init_multi(x, y, 0, 0, 0, 0) != MP_OKAY) { #ifdef WOLFSSL_SMALL_STACK XFREE(y, key->heap, DYNAMIC_TYPE_DH); XFREE(x, key->heap, DYNAMIC_TYPE_DH); #endif return MP_INIT_E; } if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY) ret = MP_READ_E; if (ret == 0 && mp_exptmod(&key->g, x, &key->p, y) != MP_OKAY) ret = MP_EXPTMOD_E; if (ret == 0) { binSz = mp_unsigned_bin_size(y); if (binSz > *pubSz) { ret = WC_KEY_SIZE_E; } } if (ret == 0 && mp_to_unsigned_bin(y, pub) != MP_OKAY) ret = MP_TO_E; if (ret == 0) *pubSz = binSz; mp_clear(y); mp_clear(x); #ifdef WOLFSSL_SMALL_STACK XFREE(y, key->heap, DYNAMIC_TYPE_DH); XFREE(x, key->heap, DYNAMIC_TYPE_DH); #endif #else ret = WC_KEY_SIZE_E; #endif return ret; } static int wc_DhGenerateKeyPair_Sync(DhKey* key, WC_RNG* rng, byte* priv, word32* privSz, byte* pub, word32* pubSz) { int ret; if (key == NULL || rng == NULL || priv == NULL || privSz == NULL || pub == NULL || pubSz == NULL) { return BAD_FUNC_ARG; } SAVE_VECTOR_REGISTERS(return _svr_ret;); ret = GeneratePrivateDh(key, rng, priv, privSz); if (ret == 0) ret = GeneratePublicDh(key, priv, *privSz, pub, pubSz); #if FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_DH_KEYGEN) if (ret == 0) ret = _ffc_validate_public_key(key, pub, *pubSz, NULL, 0, 0); if (ret == 0) ret = _ffc_pairwise_consistency_test(key, pub, *pubSz, priv, *privSz); #endif /* FIPS V5 or later || WOLFSSL_VALIDATE_DH_KEYGEN */ RESTORE_VECTOR_REGISTERS(); return ret; } #endif /* !WOLFSSL_KCAPI_DH */ #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH) static int wc_DhGenerateKeyPair_Async(DhKey* key, WC_RNG* rng, byte* priv, word32* privSz, byte* pub, word32* pubSz) { int ret; #if defined(HAVE_INTEL_QA) word32 pBits; /* QAT DH sizes: 768, 1024, 1536, 2048, 3072 and 4096 bits */ pBits = mp_unsigned_bin_size(&key->p) * 8; if (pBits == 768 || pBits == 1024 || pBits == 1536 || pBits == 2048 || pBits == 3072 || pBits == 4096) { mp_int x; ret = mp_init(&x); if (ret != MP_OKAY) return ret; ret = GeneratePrivateDh(key, rng, priv, privSz); if (ret == 0) ret = mp_read_unsigned_bin(&x, priv, *privSz); if (ret == MP_OKAY) ret = wc_mp_to_bigint(&x, &x.raw); if (ret == MP_OKAY) ret = wc_mp_to_bigint(&key->p, &key->p.raw); if (ret == MP_OKAY) ret = wc_mp_to_bigint(&key->g, &key->g.raw); if (ret == MP_OKAY) ret = IntelQaDhKeyGen(&key->asyncDev, &key->p.raw, &key->g.raw, &x.raw, pub, pubSz); mp_clear(&x); return ret; } #elif defined(HAVE_CAVIUM) /* TODO: Not implemented - use software for now */ #else /* WOLFSSL_ASYNC_CRYPT_TEST */ if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_DH_GEN)) { WC_ASYNC_TEST* testDev = &key->asyncDev.test; testDev->dhGen.key = key; testDev->dhGen.rng = rng; testDev->dhGen.priv = priv; testDev->dhGen.privSz = privSz; testDev->dhGen.pub = pub; testDev->dhGen.pubSz = pubSz; return WC_PENDING_E; } #endif /* otherwise use software DH */ ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz); return ret; } #endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_DH */ /* Check DH Public Key for invalid numbers, optionally allowing * the public key to be checked against the large prime (q). * If q is NULL, the q value of key is used. * Check per process in SP 800-56Ar3, section 5.6.2.3.1 or 2. * * key DH key group parameters. * pub Public Key. * pubSz Public Key size. * prime Large prime (q), optionally NULL to skip check * primeSz Size of large prime * partial Do the partial test process. (section 5.6.2.3.2) * * returns 0 on success or error code */ static int _ffc_validate_public_key(DhKey* key, const byte* pub, word32 pubSz, const byte* prime, word32 primeSz, int partial) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK mp_int* y = NULL; mp_int* p = NULL; mp_int* q = NULL; #else mp_int y[1]; mp_int p[1]; mp_int q[1]; #endif if (key == NULL || pub == NULL) { return BAD_FUNC_ARG; } #ifdef WOLFSSL_SMALL_STACK y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (y == NULL) return MEMORY_E; p = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (p == NULL) { XFREE(y, key->heap, DYNAMIC_TYPE_DH); return MEMORY_E; } q = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (q == NULL) { XFREE(p, key->heap, DYNAMIC_TYPE_DH); XFREE(y, key->heap, DYNAMIC_TYPE_DH); return MEMORY_E; } #endif if (mp_init_multi(y, p, q, NULL, NULL, NULL) != MP_OKAY) { #ifdef WOLFSSL_SMALL_STACK XFREE(q, key->heap, DYNAMIC_TYPE_DH); XFREE(p, key->heap, DYNAMIC_TYPE_DH); XFREE(y, key->heap, DYNAMIC_TYPE_DH); #endif return MP_INIT_E; } SAVE_VECTOR_REGISTERS(ret = _svr_ret;); if (mp_read_unsigned_bin(y, pub, pubSz) != MP_OKAY) { ret = MP_READ_E; } if (ret == 0 && prime != NULL) { if (mp_read_unsigned_bin(q, prime, primeSz) != MP_OKAY) ret = MP_READ_E; } else if (mp_iszero(&key->q) == MP_NO) { /* use q available in DhKey */ if (mp_copy(&key->q, q) != MP_OKAY) ret = MP_INIT_E; } /* SP 800-56Ar3, section 5.6.2.3.2 */ /* pub (y) should not be 0 or 1 */ if (ret == 0 && mp_cmp_d(y, 2) == MP_LT) { ret = MP_CMP_E; } /* pub (y) shouldn't be greater than or equal to p - 1 */ if (ret == 0 && mp_copy(&key->p, p) != MP_OKAY) { ret = MP_INIT_E; } if (ret == 0 && mp_sub_d(p, 2, p) != MP_OKAY) { ret = MP_SUB_E; } if (ret == 0 && mp_cmp(y, p) == MP_GT) { ret = MP_CMP_E; } if (!partial) { if (ret == 0 && (prime != NULL || (mp_iszero(&key->q) == MP_NO) )) { /* restore key->p into p */ if (mp_copy(&key->p, p) != MP_OKAY) ret = MP_INIT_E; } /* SP 800-56Ar3, section 5.6.2.3.1, process step 2 */ if (ret == 0 && prime != NULL) { #ifdef WOLFSSL_HAVE_SP_DH #ifndef WOLFSSL_SP_NO_2048 if (mp_count_bits(&key->p) == 2048) { ret = sp_ModExp_2048(y, q, p, y); if (ret != 0) ret = MP_EXPTMOD_E; } else #endif #ifndef WOLFSSL_SP_NO_3072 if (mp_count_bits(&key->p) == 3072) { ret = sp_ModExp_3072(y, q, p, y); if (ret != 0) ret = MP_EXPTMOD_E; } else #endif #ifdef WOLFSSL_SP_4096 if (mp_count_bits(&key->p) == 4096) { ret = sp_ModExp_4096(y, q, p, y); if (ret != 0) ret = MP_EXPTMOD_E; } else #endif #endif { #if !defined(WOLFSSL_SP_MATH) /* calculate (y^q) mod(p), store back into y */ if (mp_exptmod(y, q, p, y) != MP_OKAY) ret = MP_EXPTMOD_E; #else ret = WC_KEY_SIZE_E; #endif } /* verify above == 1 */ if (ret == 0 && mp_cmp_d(y, 1) != MP_EQ) ret = MP_CMP_E; } } mp_clear(y); mp_clear(p); mp_clear(q); RESTORE_VECTOR_REGISTERS(); #ifdef WOLFSSL_SMALL_STACK XFREE(q, key->heap, DYNAMIC_TYPE_DH); XFREE(p, key->heap, DYNAMIC_TYPE_DH); XFREE(y, key->heap, DYNAMIC_TYPE_DH); #endif return ret; } /* Performs a full public-key validation routine. */ int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz, const byte* prime, word32 primeSz) { return _ffc_validate_public_key(key, pub, pubSz, prime, primeSz, 0); } /* Check DH Public Key for invalid numbers. Performs a partial public-key * validation routine. * * key DH key group parameters. * pub Public Key. * pubSz Public Key size. * * returns 0 on success or error code */ int wc_DhCheckPubKey(DhKey* key, const byte* pub, word32 pubSz) { return _ffc_validate_public_key(key, pub, pubSz, NULL, 0, 1); } /** * Quick validity check of public key value against prime. * Checks are: * - Public key not 0 or 1 * - Public key not equal to prime or prime - 1 * - Public key not bigger than prime. * * prime Big-endian encoding of prime in bytes. * primeSz Size of prime in bytes. * pub Big-endian encoding of public key in bytes. * pubSz Size of public key in bytes. */ int wc_DhCheckPubValue(const byte* prime, word32 primeSz, const byte* pub, word32 pubSz) { int ret = 0; word32 i; for (i = 0; i < pubSz && pub[i] == 0; i++) { } pubSz -= i; pub += i; if (pubSz == 0 || (pubSz == 1 && pub[0] == 1)) ret = MP_VAL; else if (pubSz == primeSz) { for (i = 0; i < pubSz-1 && pub[i] == prime[i]; i++) { } if (i == pubSz-1 && (pub[i] == prime[i] || pub[i] == prime[i] - 1)) ret = MP_VAL; else if (pub[i] > prime[i]) ret = MP_VAL; } else if (pubSz > primeSz) ret = MP_VAL; return ret; } /* Check DH Private Key for invalid numbers, optionally allowing * the private key to be checked against the large prime (q). * Check per process in SP 800-56Ar3, section 5.6.2.1.2. * * key DH key group parameters. * priv Private Key. * privSz Private Key size. * prime Large prime (q), optionally NULL to skip check * primeSz Size of large prime * * returns 0 on success or error code */ int wc_DhCheckPrivKey_ex(DhKey* key, const byte* priv, word32 privSz, const byte* prime, word32 primeSz) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK mp_int* x = NULL; mp_int* q = NULL; #else mp_int x[1]; mp_int q[1]; #endif if (key == NULL || priv == NULL) { return BAD_FUNC_ARG; } #ifdef WOLFSSL_SMALL_STACK x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (x == NULL) return MEMORY_E; q = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (q == NULL) { XFREE(x, key->heap, DYNAMIC_TYPE_DH); return MEMORY_E; } #endif if (mp_init_multi(x, q, NULL, NULL, NULL, NULL) != MP_OKAY) { #ifdef WOLFSSL_SMALL_STACK XFREE(q, key->heap, DYNAMIC_TYPE_DH); XFREE(x, key->heap, DYNAMIC_TYPE_DH); #endif return MP_INIT_E; } if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY) { ret = MP_READ_E; } if (ret == 0) { #ifdef WOLFSSL_CHECK_MEM_ZERO mp_memzero_add("wc_DhCheckPrivKey_ex x", x); #endif if (prime != NULL) { if (mp_read_unsigned_bin(q, prime, primeSz) != MP_OKAY) ret = MP_READ_E; } else if (mp_iszero(&key->q) == MP_NO) { /* use q available in DhKey */ if (mp_copy(&key->q, q) != MP_OKAY) ret = MP_INIT_E; } } /* priv (x) should not be 0 */ if (ret == 0) { if (mp_cmp_d(x, 0) == MP_EQ) ret = MP_CMP_E; } if (ret == 0) { if (mp_iszero(q) == MP_NO) { /* priv (x) shouldn't be greater than q - 1 */ if (mp_copy(&key->q, q) != MP_OKAY) ret = MP_INIT_E; if (ret == 0) { if (mp_sub_d(q, 1, q) != MP_OKAY) ret = MP_SUB_E; } if (ret == 0) { if (mp_cmp(x, q) == MP_GT) ret = DH_CHECK_PRIV_E; } } } mp_forcezero(x); mp_clear(q); #ifdef WOLFSSL_SMALL_STACK XFREE(q, key->heap, DYNAMIC_TYPE_DH); XFREE(x, key->heap, DYNAMIC_TYPE_DH); #elif defined(WOLFSSL_CHECK_MEM_ZERO) mp_memzero_check(x); #endif return ret; } /* Check DH Private Key for invalid numbers * * key DH key group parameters. * priv Private Key. * privSz Private Key size. * * returns 0 on success or error code */ int wc_DhCheckPrivKey(DhKey* key, const byte* priv, word32 privSz) { return wc_DhCheckPrivKey_ex(key, priv, privSz, NULL, 0); } /* Performs a Pairwise Consistency Test on an FFC key pair. */ /* Check DH Keys for pair-wise consistency per process in * SP 800-56Ar3, section 5.6.2.1.4, method (b) for FFC. */ static int _ffc_pairwise_consistency_test(DhKey* key, const byte* pub, word32 pubSz, const byte* priv, word32 privSz) { #ifdef WOLFSSL_SMALL_STACK mp_int* publicKey = NULL; mp_int* privateKey = NULL; mp_int* checkKey = NULL; #else mp_int publicKey[1]; mp_int privateKey[1]; mp_int checkKey[1]; #endif int ret = 0; if (key == NULL || pub == NULL || priv == NULL) return BAD_FUNC_ARG; if (mp_iseven(&key->p) == MP_YES) return MP_VAL; #ifdef WOLFSSL_SMALL_STACK publicKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (publicKey == NULL) return MEMORY_E; privateKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (privateKey == NULL) { XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH); return MEMORY_E; } checkKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (checkKey == NULL) { XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH); XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH); return MEMORY_E; } #endif if (mp_init_multi(publicKey, privateKey, checkKey, NULL, NULL, NULL) != MP_OKAY) { #ifdef WOLFSSL_SMALL_STACK XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH); XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH); XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH); #endif return MP_INIT_E; } SAVE_VECTOR_REGISTERS(ret = _svr_ret;); /* Load the private and public keys into big integers. */ if (mp_read_unsigned_bin(publicKey, pub, pubSz) != MP_OKAY || mp_read_unsigned_bin(privateKey, priv, privSz) != MP_OKAY) { ret = MP_READ_E; } #ifdef WOLFSSL_CHECK_MEM_ZERO mp_memzero_add("_ffc_pairwise_consistency_test privateKey", privateKey); #endif /* Calculate checkKey = g^privateKey mod p */ if (ret == 0) { #ifdef WOLFSSL_HAVE_SP_DH #ifndef WOLFSSL_SP_NO_2048 if (mp_count_bits(&key->p) == 2048) { ret = sp_ModExp_2048(&key->g, privateKey, &key->p, checkKey); if (ret != 0) ret = MP_EXPTMOD_E; } else #endif #ifndef WOLFSSL_SP_NO_3072 if (mp_count_bits(&key->p) == 3072) { ret = sp_ModExp_3072(&key->g, privateKey, &key->p, checkKey); if (ret != 0) ret = MP_EXPTMOD_E; } else #endif #ifdef WOLFSSL_SP_4096 if (mp_count_bits(&key->p) == 4096) { ret = sp_ModExp_4096(&key->g, privateKey, &key->p, checkKey); if (ret != 0) ret = MP_EXPTMOD_E; } else #endif #endif { #if !defined(WOLFSSL_SP_MATH) if (mp_exptmod(&key->g, privateKey, &key->p, checkKey) != MP_OKAY) ret = MP_EXPTMOD_E; #else ret = WC_KEY_SIZE_E; #endif } } /* Compare the calculated public key to the supplied check value. */ if (ret == 0) { if (mp_cmp(checkKey, publicKey) != MP_EQ) ret = MP_CMP_E; } mp_forcezero(privateKey); mp_clear(publicKey); mp_clear(checkKey); RESTORE_VECTOR_REGISTERS(); #ifdef WOLFSSL_SMALL_STACK XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH); XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH); XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH); #elif defined(WOLFSSL_CHECK_MEM_ZERO) mp_memzero_check(privateKey); #endif return ret; } /* Check DH Keys for pair-wise consistency per process in * SP 800-56Ar3, section 5.6.2.1.4, method (b) for FFC. * * key DH key group parameters. * pub Public Key. * pubSz Public Key size. * priv Private Key. * privSz Private Key size. * * returns 0 on success or error code */ int wc_DhCheckKeyPair(DhKey* key, const byte* pub, word32 pubSz, const byte* priv, word32 privSz) { return _ffc_pairwise_consistency_test(key, pub, pubSz, priv, privSz); } int wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng, byte* priv, word32* privSz, byte* pub, word32* pubSz) { int ret; if (key == NULL || rng == NULL || priv == NULL || privSz == NULL || pub == NULL || pubSz == NULL) { return BAD_FUNC_ARG; } #ifdef WOLFSSL_KCAPI_DH (void)priv; (void)privSz; ret = KcapiDh_MakeKey(key, pub, pubSz); #else #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH) if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_DH) { ret = wc_DhGenerateKeyPair_Async(key, rng, priv, privSz, pub, pubSz); } else #endif { ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz); } #endif /* WOLFSSL_KCAPI_DH */ return ret; } #ifndef WOLFSSL_KCAPI_DH static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz, const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK mp_int* y = NULL; #if !defined(WOLFSSL_SP_MATH) mp_int* x = NULL; mp_int* z = NULL; #endif #else mp_int y[1]; #if !defined(WOLFSSL_SP_MATH) mp_int x[1]; mp_int z[1]; #endif #endif if (mp_iseven(&key->p) == MP_YES) { return MP_VAL; } #ifdef WOLFSSL_VALIDATE_FFC_IMPORT if (wc_DhCheckPrivKey(key, priv, privSz) != 0) { WOLFSSL_MSG("wc_DhAgree wc_DhCheckPrivKey failed"); return DH_CHECK_PRIV_E; } if (wc_DhCheckPubKey(key, otherPub, pubSz) != 0) { WOLFSSL_MSG("wc_DhAgree wc_DhCheckPubKey failed"); return DH_CHECK_PUB_E; } #endif #ifdef WOLFSSL_SMALL_STACK y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (y == NULL) return MEMORY_E; #if !defined(WOLFSSL_SP_MATH) x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (x == NULL) { XFREE(y, key->heap, DYNAMIC_TYPE_DH); return MEMORY_E; } z = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH); if (z == NULL) { XFREE(x, key->heap, DYNAMIC_TYPE_DH); XFREE(y, key->heap, DYNAMIC_TYPE_DH); return MEMORY_E; } #endif #endif #ifdef WOLFSSL_HAVE_SP_DH #ifndef WOLFSSL_SP_NO_2048 if (mp_count_bits(&key->p) == 2048) { if (mp_init(y) != MP_OKAY) return MP_INIT_E; SAVE_VECTOR_REGISTERS(ret = _svr_ret;); if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY) ret = MP_READ_E; if (ret == 0) ret = sp_DhExp_2048(y, priv, privSz, &key->p, agree, agreeSz); mp_clear(y); RESTORE_VECTOR_REGISTERS(); #ifdef WOLFSSL_SMALL_STACK #if !defined(WOLFSSL_SP_MATH) XFREE(z, key->heap, DYNAMIC_TYPE_DH); XFREE(x, key->heap, DYNAMIC_TYPE_DH); #endif XFREE(y, key->heap, DYNAMIC_TYPE_DH); #endif return ret; } #endif #ifndef WOLFSSL_SP_NO_3072 if (mp_count_bits(&key->p) == 3072) { if (mp_init(y) != MP_OKAY) return MP_INIT_E; SAVE_VECTOR_REGISTERS(ret = _svr_ret;); if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY) ret = MP_READ_E; if (ret == 0) ret = sp_DhExp_3072(y, priv, privSz, &key->p, agree, agreeSz); mp_clear(y); RESTORE_VECTOR_REGISTERS(); #ifdef WOLFSSL_SMALL_STACK #if !defined(WOLFSSL_SP_MATH) XFREE(z, key->heap, DYNAMIC_TYPE_DH); XFREE(x, key->heap, DYNAMIC_TYPE_DH); #endif XFREE(y, key->heap, DYNAMIC_TYPE_DH); #endif return ret; } #endif #ifdef WOLFSSL_SP_4096 if (mp_count_bits(&key->p) == 4096) { if (mp_init(y) != MP_OKAY) return MP_INIT_E; SAVE_VECTOR_REGISTERS(ret = _svr_ret;); if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY) ret = MP_READ_E; if (ret == 0) ret = sp_DhExp_4096(y, priv, privSz, &key->p, agree, agreeSz); mp_clear(y); RESTORE_VECTOR_REGISTERS(); #ifdef WOLFSSL_SMALL_STACK #if !defined(WOLFSSL_SP_MATH) XFREE(z, key->heap, DYNAMIC_TYPE_DH); XFREE(x, key->heap, DYNAMIC_TYPE_DH); #endif XFREE(y, key->heap, DYNAMIC_TYPE_DH); #endif return ret; } #endif #endif #if !defined(WOLFSSL_SP_MATH) if (mp_init_multi(x, y, z, 0, 0, 0) != MP_OKAY) { #ifdef WOLFSSL_SMALL_STACK XFREE(z, key->heap, DYNAMIC_TYPE_DH); XFREE(x, key->heap, DYNAMIC_TYPE_DH); XFREE(y, key->heap, DYNAMIC_TYPE_DH); #endif return MP_INIT_E; } SAVE_VECTOR_REGISTERS(ret = _svr_ret;); if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY) ret = MP_READ_E; #ifdef WOLFSSL_CHECK_MEM_ZERO if (ret == 0) mp_memzero_add("wc_DhAgree_Sync x", x); #endif if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY) ret = MP_READ_E; if (ret == 0 && mp_exptmod(y, x, &key->p, z) != MP_OKAY) ret = MP_EXPTMOD_E; #ifdef WOLFSSL_CHECK_MEM_ZERO if (ret == 0) mp_memzero_add("wc_DhAgree_Sync z", z); #endif /* make sure z is not one (SP800-56A, 5.7.1.1) */ if (ret == 0 && (mp_cmp_d(z, 1) == MP_EQ)) ret = MP_VAL; if (ret == 0 && mp_to_unsigned_bin(z, agree) != MP_OKAY) ret = MP_TO_E; if (ret == 0) *agreeSz = mp_unsigned_bin_size(z); mp_forcezero(z); mp_clear(y); mp_forcezero(x); RESTORE_VECTOR_REGISTERS(); #else ret = WC_KEY_SIZE_E; #endif #ifdef WOLFSSL_SMALL_STACK #if !defined(WOLFSSL_SP_MATH) XFREE(z, key->heap, DYNAMIC_TYPE_DH); XFREE(x, key->heap, DYNAMIC_TYPE_DH); #endif XFREE(y, key->heap, DYNAMIC_TYPE_DH); #elif defined(WOLFSSL_CHECK_MEM_ZERO) mp_memzero_check(x); mp_memzero_check(z); #endif return ret; } #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH) static int wc_DhAgree_Async(DhKey* key, byte* agree, word32* agreeSz, const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz) { int ret; #if defined(HAVE_INTEL_QA) word32 pBits; /* QAT DH sizes: 768, 1024, 1536, 2048, 3072 and 4096 bits */ pBits = mp_unsigned_bin_size(&key->p) * 8; if (pBits == 768 || pBits == 1024 || pBits == 1536 || pBits == 2048 || pBits == 3072 || pBits == 4096) { ret = wc_mp_to_bigint(&key->p, &key->p.raw); if (ret == MP_OKAY) ret = IntelQaDhAgree(&key->asyncDev, &key->p.raw, agree, agreeSz, priv, privSz, otherPub, pubSz); return ret; } #elif defined(HAVE_CAVIUM) /* TODO: Not implemented - use software for now */ #else /* WOLFSSL_ASYNC_CRYPT_TEST */ if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_DH_AGREE)) { WC_ASYNC_TEST* testDev = &key->asyncDev.test; testDev->dhAgree.key = key; testDev->dhAgree.agree = agree; testDev->dhAgree.agreeSz = agreeSz; testDev->dhAgree.priv = priv; testDev->dhAgree.privSz = privSz; testDev->dhAgree.otherPub = otherPub; testDev->dhAgree.pubSz = pubSz; return WC_PENDING_E; } #endif /* otherwise use software DH */ ret = wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub, pubSz); return ret; } #endif /* WOLFSSL_ASYNC_CRYPT */ #endif /* !WOLFSSL_KCAPI_DH */ int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz) { int ret = 0; if (key == NULL || agree == NULL || agreeSz == NULL || priv == NULL || otherPub == NULL) { return BAD_FUNC_ARG; } #ifdef WOLFSSL_KCAPI_DH (void)priv; (void)privSz; ret = KcapiDh_SharedSecret(key, otherPub, pubSz, agree, agreeSz); #else #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH) if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_DH) { ret = wc_DhAgree_Async(key, agree, agreeSz, priv, privSz, otherPub, pubSz); } else #endif { ret = wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub, pubSz); } #endif /* WOLFSSL_KCAPI_DH */ return ret; } #ifdef WOLFSSL_DH_EXTRA WOLFSSL_LOCAL int wc_DhKeyCopy(DhKey* src, DhKey* dst) { int ret; if (!src || !dst || src == dst) { WOLFSSL_MSG("Parameters not provided or are the same"); return BAD_FUNC_ARG; } if ((ret = mp_copy(&src->p, &dst->p)) != MP_OKAY) { WOLFSSL_MSG("mp_copy error"); return ret; } if ((ret = mp_copy(&src->g, &dst->g)) != MP_OKAY) { WOLFSSL_MSG("mp_copy error"); return ret; } if ((ret = mp_copy(&src->q, &dst->q)) != MP_OKAY) { WOLFSSL_MSG("mp_copy error"); return ret; } if ((ret = mp_copy(&src->pub, &dst->pub)) != MP_OKAY) { WOLFSSL_MSG("mp_copy error"); return ret; } if ((ret = mp_copy(&src->priv, &dst->priv)) != MP_OKAY) { WOLFSSL_MSG("mp_copy error"); return ret; } #ifdef WOLFSSL_CHECK_MEM_ZERO mp_memzero_add("wc_DhKeyCopy dst->priv", &dst->priv); #endif dst->heap = src->heap; return MP_OKAY; } /* Sets private and public key in DhKey if both are available, otherwise sets either private or public key, depending on which is available. */ int wc_DhImportKeyPair(DhKey* key, const byte* priv, word32 privSz, const byte* pub, word32 pubSz) { byte havePriv, havePub; if (key == NULL) { return BAD_FUNC_ARG; } havePriv = ( (priv != NULL) && (privSz > 0) ); havePub = ( (pub != NULL) && (pubSz > 0) ); if (!havePub && !havePriv) { WOLFSSL_MSG("No Public or Private Key to Set"); return BAD_FUNC_ARG; } /* Set Private Key */ if (havePriv) { /* may have leading 0 */ if (priv[0] == 0) { privSz--; priv++; } if (mp_init(&key->priv) != MP_OKAY) havePriv = 0; } if (havePriv) { if (mp_read_unsigned_bin(&key->priv, priv, privSz) != MP_OKAY) { mp_clear(&key->priv); havePriv = 0; } else { WOLFSSL_MSG("DH Private Key Set"); #ifdef WOLFSSL_CHECK_MEM_ZERO mp_memzero_add("wc_DhImportKeyPair key->priv", &key->priv); #endif } } /* Set Public Key */ if (havePub) { /* may have leading 0 */ if (pub[0] == 0) { pubSz--; pub++; } if (mp_init(&key->pub) != MP_OKAY) havePub = 0; } if (havePub) { if (mp_read_unsigned_bin(&key->pub, pub, pubSz) != MP_OKAY) { mp_clear(&key->pub); havePub = 0; if (havePriv) { mp_forcezero(&key->priv); havePriv = 0; /* set to 0 to error out with failed read pub */ } } else { WOLFSSL_MSG("DH Public Key Set"); } } if (havePriv == 0 && havePub == 0) { return MEMORY_E; } return 0; } /* Can be used with WOLFSSL_DH_EXTRA when key is loaded with wc_DhKeyDecode or wc_DhImportKeyPair */ int wc_DhExportKeyPair(DhKey* key, byte* priv, word32* pPrivSz, byte* pub, word32* pPubSz) { int ret = 0; word32 pubSz, privSz; if (key == NULL || (priv && pPrivSz == NULL) || (pub && pPubSz == NULL)) { return BAD_FUNC_ARG; } if (priv) { privSz = mp_unsigned_bin_size(&key->priv); if (privSz > *pPrivSz) { return BUFFER_E; } *pPrivSz = privSz; ret |= mp_to_unsigned_bin(&key->priv, priv); } if (pub) { pubSz = mp_unsigned_bin_size(&key->pub); if (pubSz > *pPubSz) { return BUFFER_E; } *pPubSz = pubSz; ret |= mp_to_unsigned_bin(&key->pub, pub); } if (ret != 0) ret = ASN_DH_KEY_E; return ret; } #endif /* WOLFSSL_DH_EXTRA */ static int _DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz, const byte* q, word32 qSz, int trusted, WC_RNG* rng) { int ret = 0; mp_int* keyP = NULL; mp_int* keyG = NULL; if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0) { ret = BAD_FUNC_ARG; } SAVE_VECTOR_REGISTERS(return _svr_ret;); if (ret == 0) { /* may have leading 0 */ if (p[0] == 0) { pSz--; p++; } if (g[0] == 0) { gSz--; g++; } if (q != NULL) { if (q[0] == 0) { qSz--; q++; } } if (mp_init(&key->p) != MP_OKAY) ret = MP_INIT_E; } if (ret == 0) { if (mp_read_unsigned_bin(&key->p, p, pSz) != MP_OKAY) ret = ASN_DH_KEY_E; else keyP = &key->p; } if (ret == 0 && !trusted) { int isPrime = 0; if (rng != NULL) ret = mp_prime_is_prime_ex(keyP, 8, &isPrime, rng); else ret = mp_prime_is_prime(keyP, 8, &isPrime); if (ret == 0 && isPrime == 0) ret = DH_CHECK_PUB_E; } if (ret == 0 && mp_init(&key->g) != MP_OKAY) ret = MP_INIT_E; if (ret == 0) { if (mp_read_unsigned_bin(&key->g, g, gSz) != MP_OKAY) ret = ASN_DH_KEY_E; else keyG = &key->g; } if (ret == 0 && q != NULL) { if (mp_init(&key->q) != MP_OKAY) ret = MP_INIT_E; } if (ret == 0 && q != NULL) { if (mp_read_unsigned_bin(&key->q, q, qSz) != MP_OKAY) ret = MP_INIT_E; else key->trustedGroup = trusted; } if (ret != 0 && key != NULL) { if (keyG) mp_clear(keyG); if (keyP) mp_clear(keyP); } RESTORE_VECTOR_REGISTERS(); return ret; } int wc_DhSetCheckKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz, const byte* q, word32 qSz, int trusted, WC_RNG* rng) { return _DhSetKey(key, p, pSz, g, gSz, q, qSz, trusted, rng); } int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz, const byte* q, word32 qSz) { return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 0, NULL); } /* not in asn anymore since no actual asn types used */ int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz) { /* This should not have trusted set. */ return _DhSetKey(key, p, pSz, g, gSz, NULL, 0, 1, NULL); } int wc_DhSetNamedKey(DhKey* key, int name) { const byte* p = NULL; const byte* g = NULL; const byte* q = NULL; word32 pSz = 0, gSz = 0, qSz = 0; switch (name) { #ifdef HAVE_FFDHE_2048 case WC_FFDHE_2048: p = dh_ffdhe2048_p; pSz = sizeof(dh_ffdhe2048_p); g = dh_ffdhe2048_g; gSz = sizeof(dh_ffdhe2048_g); #ifdef HAVE_FFDHE_Q q = dh_ffdhe2048_q; qSz = sizeof(dh_ffdhe2048_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_2048 */ #ifdef HAVE_FFDHE_3072 case WC_FFDHE_3072: p = dh_ffdhe3072_p; pSz = sizeof(dh_ffdhe3072_p); g = dh_ffdhe3072_g; gSz = sizeof(dh_ffdhe3072_g); #ifdef HAVE_FFDHE_Q q = dh_ffdhe3072_q; qSz = sizeof(dh_ffdhe3072_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_3072 */ #ifdef HAVE_FFDHE_4096 case WC_FFDHE_4096: p = dh_ffdhe4096_p; pSz = sizeof(dh_ffdhe4096_p); g = dh_ffdhe4096_g; gSz = sizeof(dh_ffdhe4096_g); #ifdef HAVE_FFDHE_Q q = dh_ffdhe4096_q; qSz = sizeof(dh_ffdhe4096_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_4096 */ #ifdef HAVE_FFDHE_6144 case WC_FFDHE_6144: p = dh_ffdhe6144_p; pSz = sizeof(dh_ffdhe6144_p); g = dh_ffdhe6144_g; gSz = sizeof(dh_ffdhe6144_g); #ifdef HAVE_FFDHE_Q q = dh_ffdhe6144_q; qSz = sizeof(dh_ffdhe6144_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_6144 */ #ifdef HAVE_FFDHE_8192 case WC_FFDHE_8192: p = dh_ffdhe8192_p; pSz = sizeof(dh_ffdhe8192_p); g = dh_ffdhe8192_g; gSz = sizeof(dh_ffdhe8192_g); #ifdef HAVE_FFDHE_Q q = dh_ffdhe8192_q; qSz = sizeof(dh_ffdhe8192_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_8192 */ default: break; } return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 1, NULL); } word32 wc_DhGetNamedKeyMinSize(int name) { int size; switch (name) { #ifdef HAVE_FFDHE_2048 case WC_FFDHE_2048: size = 29; break; #endif /* HAVE_FFDHE_2048 */ #ifdef HAVE_FFDHE_3072 case WC_FFDHE_3072: size = 34; break; #endif /* HAVE_FFDHE_3072 */ #ifdef HAVE_FFDHE_4096 case WC_FFDHE_4096: size = 39; break; #endif /* HAVE_FFDHE_4096 */ #ifdef HAVE_FFDHE_6144 case WC_FFDHE_6144: size = 46; break; #endif /* HAVE_FFDHE_6144 */ #ifdef HAVE_FFDHE_8192 case WC_FFDHE_8192: size = 52; break; #endif /* HAVE_FFDHE_8192 */ default: size = 0; } return size; } /* Returns 1: params match * 0: params differ */ int wc_DhCmpNamedKey(int name, int noQ, const byte* p, word32 pSz, const byte* g, word32 gSz, const byte* q, word32 qSz) { const byte* pCmp = NULL; const byte* qCmp = NULL; const byte* gCmp = NULL; word32 pCmpSz = 0, qCmpSz = 0, gCmpSz = 0; int cmp = 0, goodName = 1; switch (name) { #ifdef HAVE_FFDHE_2048 case WC_FFDHE_2048: pCmp = dh_ffdhe2048_p; pCmpSz = sizeof(dh_ffdhe2048_p); gCmp = dh_ffdhe2048_g; gCmpSz = sizeof(dh_ffdhe2048_g); #ifdef HAVE_FFDHE_Q qCmp = dh_ffdhe2048_q; qCmpSz = sizeof(dh_ffdhe2048_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_2048 */ #ifdef HAVE_FFDHE_3072 case WC_FFDHE_3072: pCmp = dh_ffdhe3072_p; pCmpSz = sizeof(dh_ffdhe3072_p); gCmp = dh_ffdhe3072_g; gCmpSz = sizeof(dh_ffdhe3072_g); #ifdef HAVE_FFDHE_Q qCmp = dh_ffdhe3072_q; qCmpSz = sizeof(dh_ffdhe3072_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_3072 */ #ifdef HAVE_FFDHE_4096 case WC_FFDHE_4096: pCmp = dh_ffdhe4096_p; pCmpSz = sizeof(dh_ffdhe4096_p); gCmp = dh_ffdhe4096_g; gCmpSz = sizeof(dh_ffdhe4096_g); #ifdef HAVE_FFDHE_Q qCmp = dh_ffdhe4096_q; qCmpSz = sizeof(dh_ffdhe4096_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_4096 */ #ifdef HAVE_FFDHE_6144 case WC_FFDHE_6144: pCmp = dh_ffdhe6144_p; pCmpSz = sizeof(dh_ffdhe6144_p); gCmp = dh_ffdhe6144_g; gCmpSz = sizeof(dh_ffdhe6144_g); #ifdef HAVE_FFDHE_Q qCmp = dh_ffdhe6144_q; qCmpSz = sizeof(dh_ffdhe6144_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_6144 */ #ifdef HAVE_FFDHE_8192 case WC_FFDHE_8192: pCmp = dh_ffdhe8192_p; pCmpSz = sizeof(dh_ffdhe8192_p); gCmp = dh_ffdhe8192_g; gCmpSz = sizeof(dh_ffdhe8192_g); #ifdef HAVE_FFDHE_Q qCmp = dh_ffdhe8192_q; qCmpSz = sizeof(dh_ffdhe8192_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_8192 */ default: goodName = 0; } cmp = goodName && (pSz == pCmpSz) && (gSz == gCmpSz) && (noQ || ((qCmp != NULL) && (qSz == qCmpSz) && XMEMCMP(q, qCmp, qCmpSz) == 0)) && (XMEMCMP(p, pCmp, pCmpSz) == 0) && (XMEMCMP(g, gCmp, gCmpSz) == 0); return cmp; } int wc_DhGetNamedKeyParamSize(int name, word32* p, word32* g, word32* q) { word32 pSz = 0, gSz = 0, qSz = 0; switch (name) { #ifdef HAVE_FFDHE_2048 case WC_FFDHE_2048: pSz = sizeof(dh_ffdhe2048_p); gSz = sizeof(dh_ffdhe2048_g); #ifdef HAVE_FFDHE_Q qSz = sizeof(dh_ffdhe2048_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_2048 */ #ifdef HAVE_FFDHE_3072 case WC_FFDHE_3072: pSz = sizeof(dh_ffdhe3072_p); gSz = sizeof(dh_ffdhe3072_g); #ifdef HAVE_FFDHE_Q qSz = sizeof(dh_ffdhe3072_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_3072 */ #ifdef HAVE_FFDHE_4096 case WC_FFDHE_4096: pSz = sizeof(dh_ffdhe4096_p); gSz = sizeof(dh_ffdhe4096_g); #ifdef HAVE_FFDHE_Q qSz = sizeof(dh_ffdhe4096_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_4096 */ #ifdef HAVE_FFDHE_6144 case WC_FFDHE_6144: pSz = sizeof(dh_ffdhe6144_p); gSz = sizeof(dh_ffdhe6144_g); #ifdef HAVE_FFDHE_Q qSz = sizeof(dh_ffdhe6144_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_6144 */ #ifdef HAVE_FFDHE_8192 case WC_FFDHE_8192: pSz = sizeof(dh_ffdhe8192_p); gSz = sizeof(dh_ffdhe8192_g); #ifdef HAVE_FFDHE_Q qSz = sizeof(dh_ffdhe8192_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_8192 */ default: break; } if (p != NULL) *p = pSz; if (g != NULL) *g = gSz; if (q != NULL) *q = qSz; return 0; } int wc_DhCopyNamedKey(int name, byte* p, word32* pSz, byte* g, word32* gSz, byte* q, word32* qSz) { const byte* pC = NULL; const byte* gC = NULL; const byte* qC = NULL; word32 pCSz = 0, gCSz = 0, qCSz = 0; switch (name) { #ifdef HAVE_FFDHE_2048 case WC_FFDHE_2048: pC = dh_ffdhe2048_p; pCSz = sizeof(dh_ffdhe2048_p); gC = dh_ffdhe2048_g; gCSz = sizeof(dh_ffdhe2048_g); #ifdef HAVE_FFDHE_Q qC = dh_ffdhe2048_q; qCSz = sizeof(dh_ffdhe2048_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_2048 */ #ifdef HAVE_FFDHE_3072 case WC_FFDHE_3072: pC = dh_ffdhe3072_p; pCSz = sizeof(dh_ffdhe3072_p); gC = dh_ffdhe3072_g; gCSz = sizeof(dh_ffdhe3072_g); #ifdef HAVE_FFDHE_Q qC = dh_ffdhe3072_q; qCSz = sizeof(dh_ffdhe3072_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_3072 */ #ifdef HAVE_FFDHE_4096 case WC_FFDHE_4096: pC = dh_ffdhe4096_p; pCSz = sizeof(dh_ffdhe4096_p); gC = dh_ffdhe4096_g; gCSz = sizeof(dh_ffdhe4096_g); #ifdef HAVE_FFDHE_Q qC = dh_ffdhe4096_q; qCSz = sizeof(dh_ffdhe4096_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_4096 */ #ifdef HAVE_FFDHE_6144 case WC_FFDHE_6144: pC = dh_ffdhe6144_p; pCSz = sizeof(dh_ffdhe6144_p); gC = dh_ffdhe6144_g; gCSz = sizeof(dh_ffdhe6144_g); #ifdef HAVE_FFDHE_Q qC = dh_ffdhe6144_q; qCSz = sizeof(dh_ffdhe6144_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_6144 */ #ifdef HAVE_FFDHE_8192 case WC_FFDHE_8192: pC = dh_ffdhe8192_p; pCSz = sizeof(dh_ffdhe8192_p); gC = dh_ffdhe8192_g; gCSz = sizeof(dh_ffdhe8192_g); #ifdef HAVE_FFDHE_Q qC = dh_ffdhe8192_q; qCSz = sizeof(dh_ffdhe8192_q); #endif /* HAVE_FFDHE_Q */ break; #endif /* HAVE_FFDHE_8192 */ default: break; } if (p != NULL && pC != NULL) XMEMCPY(p, pC, pCSz); if (pSz != NULL) *pSz = pCSz; if (g != NULL && gC != NULL) XMEMCPY(g, gC, gCSz); if (gSz != NULL) *gSz = gCSz; if (q != NULL && qC != NULL) XMEMCPY(q, qC, qCSz); if (qSz != NULL) *qSz = qCSz; return 0; } #ifdef WOLFSSL_KEY_GEN /* modulus_size in bits */ int wc_DhGenerateParams(WC_RNG *rng, int modSz, DhKey *dh) { #ifdef WOLFSSL_SMALL_STACK mp_int *tmp = NULL, *tmp2 = NULL; #else mp_int tmp[1], tmp2[2]; #endif int groupSz = 0, bufSz = 0, primeCheckCount = 0, primeCheck = MP_NO, ret = 0; unsigned char *buf = NULL; if (rng == NULL || dh == NULL) ret = BAD_FUNC_ARG; /* set group size in bytes from modulus size * FIPS 186-4 defines valid values (1024, 160) (2048, 256) (3072, 256) */ if (ret == 0) { switch (modSz) { case 1024: groupSz = 20; break; case 2048: case 3072: groupSz = 32; break; default: #if !defined(HAVE_FIPS) && defined(WOLFSSL_NO_DH186) /* in non fips mode attempt to match strength of group size with * mod size */ if (modSz < 2048) groupSz = 20; else groupSz = 32; #else ret = BAD_FUNC_ARG; #endif break; } } if (ret == 0) { /* modulus size in bytes */ modSz /= WOLFSSL_BIT_SIZE; bufSz = modSz - groupSz; /* allocate ram */ buf = (unsigned char *)XMALLOC(bufSz, dh->heap, DYNAMIC_TYPE_TMP_BUFFER); if (buf == NULL) ret = MEMORY_E; } /* make a random string that will be multiplied against q */ if (ret == 0) ret = wc_RNG_GenerateBlock(rng, buf, bufSz); #ifdef WOLFSSL_SMALL_STACK if (ret == 0) { if (((tmp = (mp_int *)XMALLOC(sizeof(*tmp), NULL, DYNAMIC_TYPE_WOLF_BIGINT)) == NULL) || ((tmp2 = (mp_int *)XMALLOC(sizeof(*tmp2), NULL, DYNAMIC_TYPE_WOLF_BIGINT)) == NULL)) ret = MEMORY_E; } #endif SAVE_VECTOR_REGISTERS(ret = _svr_ret;); if (ret == 0) { /* force magnitude */ buf[0] |= 0xC0; /* force even */ buf[bufSz - 1] &= ~1; if (mp_init_multi(tmp, tmp2, &dh->p, &dh->q, &dh->g, 0) != MP_OKAY) { ret = MP_INIT_E; } } if (ret == 0) { if (mp_read_unsigned_bin(tmp2, buf, bufSz) != MP_OKAY) ret = MP_READ_E; } /* make our prime q */ if (ret == 0) { if (mp_rand_prime(&dh->q, groupSz, rng, NULL) != MP_OKAY) ret = PRIME_GEN_E; } /* p = random * q */ if (ret == 0) { if (mp_mul(&dh->q, tmp2, &dh->p) != MP_OKAY) ret = MP_MUL_E; } /* p = random * q + 1, so q is a prime divisor of p-1 */ if (ret == 0) { if (mp_add_d(&dh->p, 1, &dh->p) != MP_OKAY) ret = MP_ADD_E; } /* tmp = 2q */ if (ret == 0) { if (mp_add(&dh->q, &dh->q, tmp) != MP_OKAY) ret = MP_ADD_E; } /* loop until p is prime */ if (ret == 0) { do { if (mp_prime_is_prime_ex(&dh->p, 8, &primeCheck, rng) != MP_OKAY) ret = PRIME_GEN_E; if (primeCheck != MP_YES) { /* p += 2q */ if (mp_add(tmp, &dh->p, &dh->p) != MP_OKAY) ret = MP_ADD_E; else primeCheckCount++; } } while (ret == 0 && primeCheck == MP_NO); } /* tmp2 += (2*loop_check_prime) * to have p = (q * tmp2) + 1 prime */ if ((ret == 0) && (primeCheckCount)) { if (mp_add_d(tmp2, 2 * primeCheckCount, tmp2) != MP_OKAY) ret = MP_ADD_E; } /* find a value g for which g^tmp2 != 1 */ if ((ret == 0) && (mp_set(&dh->g, 1) != MP_OKAY)) ret = MP_ZERO_E; if (ret == 0) { do { if (mp_add_d(&dh->g, 1, &dh->g) != MP_OKAY) ret = MP_ADD_E; else if (mp_exptmod(&dh->g, tmp2, &dh->p, tmp) != MP_OKAY) ret = MP_EXPTMOD_E; } while (ret == 0 && mp_cmp_d(tmp, 1) == MP_EQ); } if (ret == 0) { /* at this point tmp generates a group of order q mod p */ #ifndef USE_FAST_MATH /* Exchanging is quick when the data pointer can be copied. */ mp_exch(tmp, &dh->g); #else mp_copy(tmp, &dh->g); #endif } /* clear the parameters if there was an error */ if ((ret != 0) && (dh != NULL)) { mp_clear(&dh->q); mp_clear(&dh->p); mp_clear(&dh->g); } RESTORE_VECTOR_REGISTERS(); if (buf != NULL) { ForceZero(buf, bufSz); if (dh != NULL) { XFREE(buf, dh->heap, DYNAMIC_TYPE_TMP_BUFFER); } } #ifdef WOLFSSL_SMALL_STACK if (tmp != NULL) { mp_clear(tmp); XFREE(tmp, NULL, DYNAMIC_TYPE_WOLF_BIGINT); } if (tmp2 != NULL) { mp_clear(tmp2); XFREE(tmp2, NULL, DYNAMIC_TYPE_WOLF_BIGINT); } #else mp_clear(tmp); mp_clear(tmp2); #endif return ret; } /* Export raw DH parameters from DhKey structure * * dh - pointer to initialized DhKey structure * p - output location for DH (p) parameter * pSz - [IN/OUT] size of output buffer for p, size of p * q - output location for DH (q) parameter * qSz - [IN/OUT] size of output buffer for q, size of q * g - output location for DH (g) parameter * gSz - [IN/OUT] size of output buffer for g, size of g * * If p, q, and g pointers are all passed in as NULL, the function * will set pSz, qSz, and gSz to the required output buffer sizes for p, * q, and g. In this case, the function will return LENGTH_ONLY_E. * * returns 0 on success, negative upon failure */ int wc_DhExportParamsRaw(DhKey* dh, byte* p, word32* pSz, byte* q, word32* qSz, byte* g, word32* gSz) { int ret = 0; word32 pLen = 0, qLen = 0, gLen = 0; if (dh == NULL || pSz == NULL || qSz == NULL || gSz == NULL) ret = BAD_FUNC_ARG; /* get required output buffer sizes */ if (ret == 0) { pLen = mp_unsigned_bin_size(&dh->p); qLen = mp_unsigned_bin_size(&dh->q); gLen = mp_unsigned_bin_size(&dh->g); /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */ if (p == NULL && q == NULL && g == NULL) { *pSz = pLen; *qSz = qLen; *gSz = gLen; ret = LENGTH_ONLY_E; } } if (ret == 0) { if (p == NULL || q == NULL || g == NULL) ret = BAD_FUNC_ARG; } /* export p */ if (ret == 0) { if (*pSz < pLen) { WOLFSSL_MSG("Output buffer for DH p parameter too small, " "required size placed into pSz"); *pSz = pLen; ret = BUFFER_E; } } if (ret == 0) { *pSz = pLen; if (mp_to_unsigned_bin(&dh->p, p) != MP_OKAY) ret = MP_TO_E; } /* export q */ if (ret == 0) { if (*qSz < qLen) { WOLFSSL_MSG("Output buffer for DH q parameter too small, " "required size placed into qSz"); *qSz = qLen; ret = BUFFER_E; } } if (ret == 0) { *qSz = qLen; if (mp_to_unsigned_bin(&dh->q, q) != MP_OKAY) ret = MP_TO_E; } /* export g */ if (ret == 0) { if (*gSz < gLen) { WOLFSSL_MSG("Output buffer for DH g parameter too small, " "required size placed into gSz"); *gSz = gLen; ret = BUFFER_E; } } if (ret == 0) { *gSz = gLen; if (mp_to_unsigned_bin(&dh->g, g) != MP_OKAY) ret = MP_TO_E; } return ret; } #endif /* WOLFSSL_KEY_GEN */ #endif /* NO_DH */