Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
wolfSSL
Date:
Thu Apr 28 00:57:21 2016 +0000
Revision:
4:1b0d80432c79
wolfSSL 3.9.0

Who changed what in which revision?

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