Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
wolfSSL
Date:
Tue May 02 08:44:47 2017 +0000
Revision:
7:481bce714567
wolfSSL3.10.2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 7:481bce714567 1 /* dh.c
wolfSSL 7:481bce714567 2 *
wolfSSL 7:481bce714567 3 * Copyright (C) 2006-2016 wolfSSL Inc.
wolfSSL 7:481bce714567 4 *
wolfSSL 7:481bce714567 5 * This file is part of wolfSSL.
wolfSSL 7:481bce714567 6 *
wolfSSL 7:481bce714567 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 7:481bce714567 8 * it under the terms of the GNU General Public License as published by
wolfSSL 7:481bce714567 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 7:481bce714567 10 * (at your option) any later version.
wolfSSL 7:481bce714567 11 *
wolfSSL 7:481bce714567 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 7:481bce714567 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 7:481bce714567 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 7:481bce714567 15 * GNU General Public License for more details.
wolfSSL 7:481bce714567 16 *
wolfSSL 7:481bce714567 17 * You should have received a copy of the GNU General Public License
wolfSSL 7:481bce714567 18 * along with this program; if not, write to the Free Software
wolfSSL 7:481bce714567 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 7:481bce714567 20 */
wolfSSL 7:481bce714567 21
wolfSSL 7:481bce714567 22
wolfSSL 7:481bce714567 23 #ifdef HAVE_CONFIG_H
wolfSSL 7:481bce714567 24 #include <config.h>
wolfSSL 7:481bce714567 25 #endif
wolfSSL 7:481bce714567 26
wolfSSL 7:481bce714567 27 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 7:481bce714567 28
wolfSSL 7:481bce714567 29 #ifndef NO_DH
wolfSSL 7:481bce714567 30
wolfSSL 7:481bce714567 31 #include <wolfssl/wolfcrypt/dh.h>
wolfSSL 7:481bce714567 32 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 7:481bce714567 33 #include <wolfssl/wolfcrypt/logging.h>
wolfSSL 7:481bce714567 34
wolfSSL 7:481bce714567 35 #ifdef NO_INLINE
wolfSSL 7:481bce714567 36 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 7:481bce714567 37 #else
wolfSSL 7:481bce714567 38 #define WOLFSSL_MISC_INCLUDED
wolfSSL 7:481bce714567 39 #include <wolfcrypt/src/misc.c>
wolfSSL 7:481bce714567 40 #endif
wolfSSL 7:481bce714567 41
wolfSSL 7:481bce714567 42
wolfSSL 7:481bce714567 43 #if !defined(USER_MATH_LIB) && !defined(WOLFSSL_DH_CONST)
wolfSSL 7:481bce714567 44 #include <math.h>
wolfSSL 7:481bce714567 45 #define XPOW(x,y) pow((x),(y))
wolfSSL 7:481bce714567 46 #define XLOG(x) log((x))
wolfSSL 7:481bce714567 47 #else
wolfSSL 7:481bce714567 48 /* user's own math lib */
wolfSSL 7:481bce714567 49 #endif
wolfSSL 7:481bce714567 50
wolfSSL 7:481bce714567 51
wolfSSL 7:481bce714567 52 int wc_InitDhKey(DhKey* key)
wolfSSL 7:481bce714567 53 {
wolfSSL 7:481bce714567 54 int ret = 0;
wolfSSL 7:481bce714567 55
wolfSSL 7:481bce714567 56 if (key == NULL)
wolfSSL 7:481bce714567 57 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 58
wolfSSL 7:481bce714567 59 if (mp_init_multi(&key->p, &key->g, NULL, NULL, NULL, NULL) != MP_OKAY)
wolfSSL 7:481bce714567 60 ret = MEMORY_E;
wolfSSL 7:481bce714567 61
wolfSSL 7:481bce714567 62 return ret;
wolfSSL 7:481bce714567 63 }
wolfSSL 7:481bce714567 64
wolfSSL 7:481bce714567 65
wolfSSL 7:481bce714567 66 void wc_FreeDhKey(DhKey* key)
wolfSSL 7:481bce714567 67 {
wolfSSL 7:481bce714567 68 if (key) {
wolfSSL 7:481bce714567 69 #ifndef USE_FAST_MATH
wolfSSL 7:481bce714567 70 mp_clear(&key->p);
wolfSSL 7:481bce714567 71 mp_clear(&key->g);
wolfSSL 7:481bce714567 72 #endif
wolfSSL 7:481bce714567 73 }
wolfSSL 7:481bce714567 74 }
wolfSSL 7:481bce714567 75
wolfSSL 7:481bce714567 76
wolfSSL 7:481bce714567 77 /* if defined to not use floating point values do not compile in */
wolfSSL 7:481bce714567 78 #ifndef WOLFSSL_DH_CONST
wolfSSL 7:481bce714567 79 static word32 DiscreteLogWorkFactor(word32 n)
wolfSSL 7:481bce714567 80 {
wolfSSL 7:481bce714567 81 /* assuming discrete log takes about the same time as factoring */
wolfSSL 7:481bce714567 82 if (n<5)
wolfSSL 7:481bce714567 83 return 0;
wolfSSL 7:481bce714567 84 else
wolfSSL 7:481bce714567 85 return (word32)(2.4 * XPOW((double)n, 1.0/3.0) *
wolfSSL 7:481bce714567 86 XPOW(XLOG((double)n), 2.0/3.0) - 5);
wolfSSL 7:481bce714567 87 }
wolfSSL 7:481bce714567 88 #endif /* WOLFSSL_DH_CONST*/
wolfSSL 7:481bce714567 89
wolfSSL 7:481bce714567 90
wolfSSL 7:481bce714567 91 /* if not using fixed points use DiscreteLogWorkFactor function for unsual size
wolfSSL 7:481bce714567 92 otherwise round up on size needed */
wolfSSL 7:481bce714567 93 #ifndef WOLFSSL_DH_CONST
wolfSSL 7:481bce714567 94 #define WOLFSSL_DH_ROUND(x)
wolfSSL 7:481bce714567 95 #else
wolfSSL 7:481bce714567 96 #define WOLFSSL_DH_ROUND(x) \
wolfSSL 7:481bce714567 97 do { \
wolfSSL 7:481bce714567 98 if (x % 128) { \
wolfSSL 7:481bce714567 99 x &= 0xffffff80;\
wolfSSL 7:481bce714567 100 x += 128; \
wolfSSL 7:481bce714567 101 } \
wolfSSL 7:481bce714567 102 } \
wolfSSL 7:481bce714567 103 while (0)
wolfSSL 7:481bce714567 104 #endif
wolfSSL 7:481bce714567 105
wolfSSL 7:481bce714567 106
wolfSSL 7:481bce714567 107 static int GeneratePrivate(DhKey* key, WC_RNG* rng, byte* priv, word32* privSz)
wolfSSL 7:481bce714567 108 {
wolfSSL 7:481bce714567 109 int ret;
wolfSSL 7:481bce714567 110 word32 sz = mp_unsigned_bin_size(&key->p);
wolfSSL 7:481bce714567 111
wolfSSL 7:481bce714567 112 /* Table of predetermined values from the operation
wolfSSL 7:481bce714567 113 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) / WOLFSSL_BIT_SIZE + 1
wolfSSL 7:481bce714567 114 Sizes in table checked against RFC 3526
wolfSSL 7:481bce714567 115 */
wolfSSL 7:481bce714567 116 WOLFSSL_DH_ROUND(sz); /* if using fixed points only, then round up */
wolfSSL 7:481bce714567 117 switch (sz) {
wolfSSL 7:481bce714567 118 case 128: sz = 21; break;
wolfSSL 7:481bce714567 119 case 256: sz = 29; break;
wolfSSL 7:481bce714567 120 case 384: sz = 34; break;
wolfSSL 7:481bce714567 121 case 512: sz = 39; break;
wolfSSL 7:481bce714567 122 case 640: sz = 42; break;
wolfSSL 7:481bce714567 123 case 768: sz = 46; break;
wolfSSL 7:481bce714567 124 case 896: sz = 49; break;
wolfSSL 7:481bce714567 125 case 1024: sz = 52; break;
wolfSSL 7:481bce714567 126 default:
wolfSSL 7:481bce714567 127 #ifndef WOLFSSL_DH_CONST
wolfSSL 7:481bce714567 128 /* if using floating points and size of p is not in table */
wolfSSL 7:481bce714567 129 sz = min(sz, 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) /
wolfSSL 7:481bce714567 130 WOLFSSL_BIT_SIZE + 1);
wolfSSL 7:481bce714567 131 break;
wolfSSL 7:481bce714567 132 #else
wolfSSL 7:481bce714567 133 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 134 #endif
wolfSSL 7:481bce714567 135 }
wolfSSL 7:481bce714567 136
wolfSSL 7:481bce714567 137 ret = wc_RNG_GenerateBlock(rng, priv, sz);
wolfSSL 7:481bce714567 138 if (ret != 0)
wolfSSL 7:481bce714567 139 return ret;
wolfSSL 7:481bce714567 140
wolfSSL 7:481bce714567 141 priv[0] |= 0x0C;
wolfSSL 7:481bce714567 142
wolfSSL 7:481bce714567 143 *privSz = sz;
wolfSSL 7:481bce714567 144
wolfSSL 7:481bce714567 145 return 0;
wolfSSL 7:481bce714567 146 }
wolfSSL 7:481bce714567 147
wolfSSL 7:481bce714567 148
wolfSSL 7:481bce714567 149 static int GeneratePublic(DhKey* key, const byte* priv, word32 privSz,
wolfSSL 7:481bce714567 150 byte* pub, word32* pubSz)
wolfSSL 7:481bce714567 151 {
wolfSSL 7:481bce714567 152 int ret = 0;
wolfSSL 7:481bce714567 153
wolfSSL 7:481bce714567 154 mp_int x;
wolfSSL 7:481bce714567 155 mp_int y;
wolfSSL 7:481bce714567 156
wolfSSL 7:481bce714567 157 if (mp_init_multi(&x, &y, 0, 0, 0, 0) != MP_OKAY)
wolfSSL 7:481bce714567 158 return MP_INIT_E;
wolfSSL 7:481bce714567 159
wolfSSL 7:481bce714567 160 if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
wolfSSL 7:481bce714567 161 ret = MP_READ_E;
wolfSSL 7:481bce714567 162
wolfSSL 7:481bce714567 163 if (ret == 0 && mp_exptmod(&key->g, &x, &key->p, &y) != MP_OKAY)
wolfSSL 7:481bce714567 164 ret = MP_EXPTMOD_E;
wolfSSL 7:481bce714567 165
wolfSSL 7:481bce714567 166 if (ret == 0 && mp_to_unsigned_bin(&y, pub) != MP_OKAY)
wolfSSL 7:481bce714567 167 ret = MP_TO_E;
wolfSSL 7:481bce714567 168
wolfSSL 7:481bce714567 169 if (ret == 0)
wolfSSL 7:481bce714567 170 *pubSz = mp_unsigned_bin_size(&y);
wolfSSL 7:481bce714567 171
wolfSSL 7:481bce714567 172 mp_clear(&y);
wolfSSL 7:481bce714567 173 mp_clear(&x);
wolfSSL 7:481bce714567 174
wolfSSL 7:481bce714567 175 return ret;
wolfSSL 7:481bce714567 176 }
wolfSSL 7:481bce714567 177
wolfSSL 7:481bce714567 178
wolfSSL 7:481bce714567 179 int wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng, byte* priv, word32* privSz,
wolfSSL 7:481bce714567 180 byte* pub, word32* pubSz)
wolfSSL 7:481bce714567 181 {
wolfSSL 7:481bce714567 182 int ret = GeneratePrivate(key, rng, priv, privSz);
wolfSSL 7:481bce714567 183
wolfSSL 7:481bce714567 184 return (ret != 0) ? ret : GeneratePublic(key, priv, *privSz, pub, pubSz);
wolfSSL 7:481bce714567 185 }
wolfSSL 7:481bce714567 186
wolfSSL 7:481bce714567 187
wolfSSL 7:481bce714567 188 /* Check DH Public Key for invalid numbers
wolfSSL 7:481bce714567 189 *
wolfSSL 7:481bce714567 190 * key DH key group parameters.
wolfSSL 7:481bce714567 191 * pub Public Key.
wolfSSL 7:481bce714567 192 * pubSz Public Key size.
wolfSSL 7:481bce714567 193 *
wolfSSL 7:481bce714567 194 * returns 0 on success or error code
wolfSSL 7:481bce714567 195 */
wolfSSL 7:481bce714567 196 int wc_DhCheckPubKey(DhKey* key, const byte* pub, word32 pubSz)
wolfSSL 7:481bce714567 197 {
wolfSSL 7:481bce714567 198 int ret = 0;
wolfSSL 7:481bce714567 199
wolfSSL 7:481bce714567 200 mp_int x;
wolfSSL 7:481bce714567 201 mp_int y;
wolfSSL 7:481bce714567 202
wolfSSL 7:481bce714567 203 if (key == NULL || pub == NULL) {
wolfSSL 7:481bce714567 204 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 205 }
wolfSSL 7:481bce714567 206
wolfSSL 7:481bce714567 207 if (mp_init_multi(&x, &y, NULL, NULL, NULL, NULL) != MP_OKAY) {
wolfSSL 7:481bce714567 208 return MP_INIT_E;
wolfSSL 7:481bce714567 209 }
wolfSSL 7:481bce714567 210
wolfSSL 7:481bce714567 211 if (mp_read_unsigned_bin(&x, pub, pubSz) != MP_OKAY) {
wolfSSL 7:481bce714567 212 ret = MP_READ_E;
wolfSSL 7:481bce714567 213 }
wolfSSL 7:481bce714567 214
wolfSSL 7:481bce714567 215 /* pub should not be 0 or 1 */
wolfSSL 7:481bce714567 216 if (ret == 0 && mp_cmp_d(&x, 2) == MP_LT) {
wolfSSL 7:481bce714567 217 ret = MP_CMP_E;
wolfSSL 7:481bce714567 218 }
wolfSSL 7:481bce714567 219
wolfSSL 7:481bce714567 220 /* pub shouldn't be greater than or equal to p - 1 */
wolfSSL 7:481bce714567 221 if (ret == 0 && mp_copy(&key->p, &y) != MP_OKAY) {
wolfSSL 7:481bce714567 222 ret = MP_INIT_E;
wolfSSL 7:481bce714567 223 }
wolfSSL 7:481bce714567 224 if (ret == 0 && mp_sub_d(&y, 2, &y) != MP_OKAY) {
wolfSSL 7:481bce714567 225 ret = MP_SUB_E;
wolfSSL 7:481bce714567 226 }
wolfSSL 7:481bce714567 227 if (ret == 0 && mp_cmp(&x, &y) == MP_GT) {
wolfSSL 7:481bce714567 228 ret = MP_CMP_E;
wolfSSL 7:481bce714567 229 }
wolfSSL 7:481bce714567 230
wolfSSL 7:481bce714567 231 mp_clear(&y);
wolfSSL 7:481bce714567 232 mp_clear(&x);
wolfSSL 7:481bce714567 233
wolfSSL 7:481bce714567 234 return ret;
wolfSSL 7:481bce714567 235 }
wolfSSL 7:481bce714567 236
wolfSSL 7:481bce714567 237
wolfSSL 7:481bce714567 238 int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
wolfSSL 7:481bce714567 239 word32 privSz, const byte* otherPub, word32 pubSz)
wolfSSL 7:481bce714567 240 {
wolfSSL 7:481bce714567 241 int ret = 0;
wolfSSL 7:481bce714567 242
wolfSSL 7:481bce714567 243 mp_int x;
wolfSSL 7:481bce714567 244 mp_int y;
wolfSSL 7:481bce714567 245 mp_int z;
wolfSSL 7:481bce714567 246
wolfSSL 7:481bce714567 247 if (wc_DhCheckPubKey(key, otherPub, pubSz) != 0) {
wolfSSL 7:481bce714567 248 WOLFSSL_MSG("wc_DhAgree wc_DhCheckPubKey failed");
wolfSSL 7:481bce714567 249 return DH_CHECK_PUB_E;
wolfSSL 7:481bce714567 250 }
wolfSSL 7:481bce714567 251
wolfSSL 7:481bce714567 252 if (mp_init_multi(&x, &y, &z, 0, 0, 0) != MP_OKAY)
wolfSSL 7:481bce714567 253 return MP_INIT_E;
wolfSSL 7:481bce714567 254
wolfSSL 7:481bce714567 255 if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
wolfSSL 7:481bce714567 256 ret = MP_READ_E;
wolfSSL 7:481bce714567 257
wolfSSL 7:481bce714567 258 if (ret == 0 && mp_read_unsigned_bin(&y, otherPub, pubSz) != MP_OKAY)
wolfSSL 7:481bce714567 259 ret = MP_READ_E;
wolfSSL 7:481bce714567 260
wolfSSL 7:481bce714567 261 if (ret == 0 && mp_exptmod(&y, &x, &key->p, &z) != MP_OKAY)
wolfSSL 7:481bce714567 262 ret = MP_EXPTMOD_E;
wolfSSL 7:481bce714567 263
wolfSSL 7:481bce714567 264 if (ret == 0 && mp_to_unsigned_bin(&z, agree) != MP_OKAY)
wolfSSL 7:481bce714567 265 ret = MP_TO_E;
wolfSSL 7:481bce714567 266
wolfSSL 7:481bce714567 267 if (ret == 0)
wolfSSL 7:481bce714567 268 *agreeSz = mp_unsigned_bin_size(&z);
wolfSSL 7:481bce714567 269
wolfSSL 7:481bce714567 270 mp_clear(&z);
wolfSSL 7:481bce714567 271 mp_clear(&y);
wolfSSL 7:481bce714567 272 mp_clear(&x);
wolfSSL 7:481bce714567 273
wolfSSL 7:481bce714567 274 return ret;
wolfSSL 7:481bce714567 275 }
wolfSSL 7:481bce714567 276
wolfSSL 7:481bce714567 277
wolfSSL 7:481bce714567 278 /* not in asn anymore since no actual asn types used */
wolfSSL 7:481bce714567 279 int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
wolfSSL 7:481bce714567 280 word32 gSz)
wolfSSL 7:481bce714567 281 {
wolfSSL 7:481bce714567 282 if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0)
wolfSSL 7:481bce714567 283 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 284
wolfSSL 7:481bce714567 285 /* may have leading 0 */
wolfSSL 7:481bce714567 286 if (p[0] == 0) {
wolfSSL 7:481bce714567 287 pSz--; p++;
wolfSSL 7:481bce714567 288 }
wolfSSL 7:481bce714567 289
wolfSSL 7:481bce714567 290 if (g[0] == 0) {
wolfSSL 7:481bce714567 291 gSz--; g++;
wolfSSL 7:481bce714567 292 }
wolfSSL 7:481bce714567 293
wolfSSL 7:481bce714567 294 if (mp_init(&key->p) != MP_OKAY)
wolfSSL 7:481bce714567 295 return MP_INIT_E;
wolfSSL 7:481bce714567 296 if (mp_read_unsigned_bin(&key->p, p, pSz) != 0) {
wolfSSL 7:481bce714567 297 mp_clear(&key->p);
wolfSSL 7:481bce714567 298 return ASN_DH_KEY_E;
wolfSSL 7:481bce714567 299 }
wolfSSL 7:481bce714567 300
wolfSSL 7:481bce714567 301 if (mp_init(&key->g) != MP_OKAY) {
wolfSSL 7:481bce714567 302 mp_clear(&key->p);
wolfSSL 7:481bce714567 303 return MP_INIT_E;
wolfSSL 7:481bce714567 304 }
wolfSSL 7:481bce714567 305 if (mp_read_unsigned_bin(&key->g, g, gSz) != 0) {
wolfSSL 7:481bce714567 306 mp_clear(&key->g);
wolfSSL 7:481bce714567 307 mp_clear(&key->p);
wolfSSL 7:481bce714567 308 return ASN_DH_KEY_E;
wolfSSL 7:481bce714567 309 }
wolfSSL 7:481bce714567 310
wolfSSL 7:481bce714567 311 return 0;
wolfSSL 7:481bce714567 312 }
wolfSSL 7:481bce714567 313
wolfSSL 7:481bce714567 314
wolfSSL 7:481bce714567 315 #endif /* NO_DH */
wolfSSL 7:481bce714567 316
wolfSSL 7:481bce714567 317