Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
dh.c
00001 /* dh.c 00002 * 00003 * Copyright (C) 2006-2016 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * wolfSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 00020 */ 00021 00022 00023 #ifdef HAVE_CONFIG_H 00024 #include <config.h> 00025 #endif 00026 00027 #include <wolfssl/wolfcrypt/settings.h> 00028 00029 #ifndef NO_DH 00030 00031 #include <wolfssl/wolfcrypt/dh.h> 00032 #include <wolfssl/wolfcrypt/error-crypt.h> 00033 00034 #if !defined(USER_MATH_LIB) && !defined(WOLFSSL_DH_CONST) 00035 #include <math.h> 00036 #define XPOW(x,y) pow((x),(y)) 00037 #define XLOG(x) log((x)) 00038 #else 00039 /* user's own math lib */ 00040 #endif 00041 00042 00043 #if !defined(WOLFSSL_HAVE_MIN) && !defined(WOLFSSL_DH_CONST) 00044 #define WOLFSSL_HAVE_MIN 00045 00046 static INLINE word32 min(word32 a, word32 b) 00047 { 00048 return a > b ? b : a; 00049 } 00050 00051 #endif /* WOLFSSL_HAVE_MIN */ 00052 00053 00054 void wc_InitDhKey(DhKey* key) 00055 { 00056 (void)key; 00057 /* TomsFastMath doesn't use memory allocation */ 00058 #ifndef USE_FAST_MATH 00059 key->p.dp = 0; 00060 key->g.dp = 0; 00061 #endif 00062 } 00063 00064 00065 void wc_FreeDhKey(DhKey* key) 00066 { 00067 (void)key; 00068 /* TomsFastMath doesn't use memory allocation */ 00069 #ifndef USE_FAST_MATH 00070 mp_clear(&key->p); 00071 mp_clear(&key->g); 00072 #endif 00073 } 00074 00075 00076 /* if defined to not use floating point values do not compile in */ 00077 #ifndef WOLFSSL_DH_CONST 00078 static word32 DiscreteLogWorkFactor(word32 n) 00079 { 00080 /* assuming discrete log takes about the same time as factoring */ 00081 if (n<5) 00082 return 0; 00083 else 00084 return (word32)(2.4 * XPOW((double)n, 1.0/3.0) * 00085 XPOW(XLOG((double)n), 2.0/3.0) - 5); 00086 } 00087 #endif /* WOLFSSL_DH_CONST*/ 00088 00089 00090 /* if not using fixed points use DiscreteLogWorkFactor function for unsual size 00091 otherwise round up on size needed */ 00092 #ifndef WOLFSSL_DH_CONST 00093 #define WOLFSSL_DH_ROUND(x) 00094 #else 00095 #define WOLFSSL_DH_ROUND(x) \ 00096 do { \ 00097 if (x % 128) { \ 00098 x &= 0xffffff80;\ 00099 x += 128; \ 00100 } \ 00101 } \ 00102 while (0) 00103 #endif 00104 00105 00106 static int GeneratePrivate(DhKey* key, WC_RNG* rng, byte* priv, word32* privSz) 00107 { 00108 int ret; 00109 word32 sz = mp_unsigned_bin_size(&key->p); 00110 00111 /* Table of predetermined values from the operation 00112 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) / WOLFSSL_BIT_SIZE + 1 00113 Sizes in table checked against RFC 3526 00114 */ 00115 WOLFSSL_DH_ROUND(sz); /* if using fixed points only, then round up */ 00116 switch (sz) { 00117 case 128: sz = 21; break; 00118 case 256: sz = 29; break; 00119 case 384: sz = 34; break; 00120 case 512: sz = 39; break; 00121 case 640: sz = 42; break; 00122 case 768: sz = 46; break; 00123 case 896: sz = 49; break; 00124 case 1024: sz = 52; break; 00125 default: 00126 #ifndef WOLFSSL_DH_CONST 00127 /* if using floating points and size of p is not in table */ 00128 sz = min(sz, 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) / 00129 WOLFSSL_BIT_SIZE + 1); 00130 break; 00131 #else 00132 return BAD_FUNC_ARG; 00133 #endif 00134 } 00135 00136 ret = wc_RNG_GenerateBlock(rng, priv, sz); 00137 if (ret != 0) 00138 return ret; 00139 00140 priv[0] |= 0x0C; 00141 00142 *privSz = sz; 00143 00144 return 0; 00145 } 00146 00147 00148 static int GeneratePublic(DhKey* key, const byte* priv, word32 privSz, 00149 byte* pub, word32* pubSz) 00150 { 00151 int ret = 0; 00152 00153 mp_int x; 00154 mp_int y; 00155 00156 if (mp_init_multi(&x, &y, 0, 0, 0, 0) != MP_OKAY) 00157 return MP_INIT_E; 00158 00159 if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY) 00160 ret = MP_READ_E; 00161 00162 if (ret == 0 && mp_exptmod(&key->g, &x, &key->p, &y) != MP_OKAY) 00163 ret = MP_EXPTMOD_E; 00164 00165 if (ret == 0 && mp_to_unsigned_bin(&y, pub) != MP_OKAY) 00166 ret = MP_TO_E; 00167 00168 if (ret == 0) 00169 *pubSz = mp_unsigned_bin_size(&y); 00170 00171 mp_clear(&y); 00172 mp_clear(&x); 00173 00174 return ret; 00175 } 00176 00177 00178 int wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng, byte* priv, word32* privSz, 00179 byte* pub, word32* pubSz) 00180 { 00181 int ret = GeneratePrivate(key, rng, priv, privSz); 00182 00183 return (ret != 0) ? ret : GeneratePublic(key, priv, *privSz, pub, pubSz); 00184 } 00185 00186 int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv, 00187 word32 privSz, const byte* otherPub, word32 pubSz) 00188 { 00189 int ret = 0; 00190 00191 mp_int x; 00192 mp_int y; 00193 mp_int z; 00194 00195 if (mp_init_multi(&x, &y, &z, 0, 0, 0) != MP_OKAY) 00196 return MP_INIT_E; 00197 00198 if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY) 00199 ret = MP_READ_E; 00200 00201 if (ret == 0 && mp_read_unsigned_bin(&y, otherPub, pubSz) != MP_OKAY) 00202 ret = MP_READ_E; 00203 00204 if (ret == 0 && mp_exptmod(&y, &x, &key->p, &z) != MP_OKAY) 00205 ret = MP_EXPTMOD_E; 00206 00207 if (ret == 0 && mp_to_unsigned_bin(&z, agree) != MP_OKAY) 00208 ret = MP_TO_E; 00209 00210 if (ret == 0) 00211 *agreeSz = mp_unsigned_bin_size(&z); 00212 00213 mp_clear(&z); 00214 mp_clear(&y); 00215 mp_clear(&x); 00216 00217 return ret; 00218 } 00219 00220 00221 /* not in asn anymore since no actual asn types used */ 00222 int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, 00223 word32 gSz) 00224 { 00225 if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0) 00226 return BAD_FUNC_ARG; 00227 00228 /* may have leading 0 */ 00229 if (p[0] == 0) { 00230 pSz--; p++; 00231 } 00232 00233 if (g[0] == 0) { 00234 gSz--; g++; 00235 } 00236 00237 if (mp_init(&key->p) != MP_OKAY) 00238 return MP_INIT_E; 00239 if (mp_read_unsigned_bin(&key->p, p, pSz) != 0) { 00240 mp_clear(&key->p); 00241 return ASN_DH_KEY_E; 00242 } 00243 00244 if (mp_init(&key->g) != MP_OKAY) { 00245 mp_clear(&key->p); 00246 return MP_INIT_E; 00247 } 00248 if (mp_read_unsigned_bin(&key->g, g, gSz) != 0) { 00249 mp_clear(&key->g); 00250 mp_clear(&key->p); 00251 return ASN_DH_KEY_E; 00252 } 00253 00254 return 0; 00255 } 00256 00257 00258 #endif /* NO_DH */ 00259 00260
Generated on Tue Jul 12 2022 15:55:18 by
1.7.2