Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
wolfSSL
Date:
Tue May 30 01:44:10 2017 +0000
Revision:
11:cee25a834751
wolfSSL 3.11.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 11:cee25a834751 1 /* dh.c
wolfSSL 11:cee25a834751 2 *
wolfSSL 11:cee25a834751 3 * Copyright (C) 2006-2016 wolfSSL Inc.
wolfSSL 11:cee25a834751 4 *
wolfSSL 11:cee25a834751 5 * This file is part of wolfSSL.
wolfSSL 11:cee25a834751 6 *
wolfSSL 11:cee25a834751 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 11:cee25a834751 8 * it under the terms of the GNU General Public License as published by
wolfSSL 11:cee25a834751 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 11:cee25a834751 10 * (at your option) any later version.
wolfSSL 11:cee25a834751 11 *
wolfSSL 11:cee25a834751 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 11:cee25a834751 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 11:cee25a834751 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 11:cee25a834751 15 * GNU General Public License for more details.
wolfSSL 11:cee25a834751 16 *
wolfSSL 11:cee25a834751 17 * You should have received a copy of the GNU General Public License
wolfSSL 11:cee25a834751 18 * along with this program; if not, write to the Free Software
wolfSSL 11:cee25a834751 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 11:cee25a834751 20 */
wolfSSL 11:cee25a834751 21
wolfSSL 11:cee25a834751 22
wolfSSL 11:cee25a834751 23 #ifdef HAVE_CONFIG_H
wolfSSL 11:cee25a834751 24 #include <config.h>
wolfSSL 11:cee25a834751 25 #endif
wolfSSL 11:cee25a834751 26
wolfSSL 11:cee25a834751 27 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 11:cee25a834751 28
wolfSSL 11:cee25a834751 29 #ifndef NO_DH
wolfSSL 11:cee25a834751 30
wolfSSL 11:cee25a834751 31 #include <wolfssl/wolfcrypt/dh.h>
wolfSSL 11:cee25a834751 32 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 11:cee25a834751 33 #include <wolfssl/wolfcrypt/logging.h>
wolfSSL 11:cee25a834751 34
wolfSSL 11:cee25a834751 35 #ifdef NO_INLINE
wolfSSL 11:cee25a834751 36 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 11:cee25a834751 37 #else
wolfSSL 11:cee25a834751 38 #define WOLFSSL_MISC_INCLUDED
wolfSSL 11:cee25a834751 39 #include <wolfcrypt/src/misc.c>
wolfSSL 11:cee25a834751 40 #endif
wolfSSL 11:cee25a834751 41
wolfSSL 11:cee25a834751 42
wolfSSL 11:cee25a834751 43 #if !defined(USER_MATH_LIB) && !defined(WOLFSSL_DH_CONST)
wolfSSL 11:cee25a834751 44 #include <math.h>
wolfSSL 11:cee25a834751 45 #define XPOW(x,y) pow((x),(y))
wolfSSL 11:cee25a834751 46 #define XLOG(x) log((x))
wolfSSL 11:cee25a834751 47 #else
wolfSSL 11:cee25a834751 48 /* user's own math lib */
wolfSSL 11:cee25a834751 49 #endif
wolfSSL 11:cee25a834751 50
wolfSSL 11:cee25a834751 51
wolfSSL 11:cee25a834751 52 int wc_InitDhKey_ex(DhKey* key, void* heap, int devId)
wolfSSL 11:cee25a834751 53 {
wolfSSL 11:cee25a834751 54 int ret = 0;
wolfSSL 11:cee25a834751 55
wolfSSL 11:cee25a834751 56 if (key == NULL)
wolfSSL 11:cee25a834751 57 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 58
wolfSSL 11:cee25a834751 59 key->heap = heap; /* for XMALLOC/XFREE in future */
wolfSSL 11:cee25a834751 60
wolfSSL 11:cee25a834751 61 if (mp_init_multi(&key->p, &key->g, NULL, NULL, NULL, NULL) != MP_OKAY)
wolfSSL 11:cee25a834751 62 return MEMORY_E;
wolfSSL 11:cee25a834751 63
wolfSSL 11:cee25a834751 64 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
wolfSSL 11:cee25a834751 65 /* handle as async */
wolfSSL 11:cee25a834751 66 ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_DH,
wolfSSL 11:cee25a834751 67 key->heap, devId);
wolfSSL 11:cee25a834751 68 #else
wolfSSL 11:cee25a834751 69 (void)devId;
wolfSSL 11:cee25a834751 70 #endif
wolfSSL 11:cee25a834751 71
wolfSSL 11:cee25a834751 72 return ret;
wolfSSL 11:cee25a834751 73 }
wolfSSL 11:cee25a834751 74
wolfSSL 11:cee25a834751 75 int wc_InitDhKey(DhKey* key)
wolfSSL 11:cee25a834751 76 {
wolfSSL 11:cee25a834751 77 return wc_InitDhKey_ex(key, NULL, INVALID_DEVID);
wolfSSL 11:cee25a834751 78 }
wolfSSL 11:cee25a834751 79
wolfSSL 11:cee25a834751 80
wolfSSL 11:cee25a834751 81 void wc_FreeDhKey(DhKey* key)
wolfSSL 11:cee25a834751 82 {
wolfSSL 11:cee25a834751 83 if (key) {
wolfSSL 11:cee25a834751 84 mp_clear(&key->p);
wolfSSL 11:cee25a834751 85 mp_clear(&key->g);
wolfSSL 11:cee25a834751 86
wolfSSL 11:cee25a834751 87 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
wolfSSL 11:cee25a834751 88 wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_DH);
wolfSSL 11:cee25a834751 89 #endif
wolfSSL 11:cee25a834751 90 }
wolfSSL 11:cee25a834751 91 }
wolfSSL 11:cee25a834751 92
wolfSSL 11:cee25a834751 93
wolfSSL 11:cee25a834751 94 /* if defined to not use floating point values do not compile in */
wolfSSL 11:cee25a834751 95 #ifndef WOLFSSL_DH_CONST
wolfSSL 11:cee25a834751 96 static word32 DiscreteLogWorkFactor(word32 n)
wolfSSL 11:cee25a834751 97 {
wolfSSL 11:cee25a834751 98 /* assuming discrete log takes about the same time as factoring */
wolfSSL 11:cee25a834751 99 if (n < 5)
wolfSSL 11:cee25a834751 100 return 0;
wolfSSL 11:cee25a834751 101 else
wolfSSL 11:cee25a834751 102 return (word32)(2.4 * XPOW((double)n, 1.0/3.0) *
wolfSSL 11:cee25a834751 103 XPOW(XLOG((double)n), 2.0/3.0) - 5);
wolfSSL 11:cee25a834751 104 }
wolfSSL 11:cee25a834751 105 #endif /* WOLFSSL_DH_CONST*/
wolfSSL 11:cee25a834751 106
wolfSSL 11:cee25a834751 107
wolfSSL 11:cee25a834751 108 /* if not using fixed points use DiscreteLogWorkFactor function for unsual size
wolfSSL 11:cee25a834751 109 otherwise round up on size needed */
wolfSSL 11:cee25a834751 110 #ifndef WOLFSSL_DH_CONST
wolfSSL 11:cee25a834751 111 #define WOLFSSL_DH_ROUND(x)
wolfSSL 11:cee25a834751 112 #else
wolfSSL 11:cee25a834751 113 #define WOLFSSL_DH_ROUND(x) \
wolfSSL 11:cee25a834751 114 do { \
wolfSSL 11:cee25a834751 115 if (x % 128) { \
wolfSSL 11:cee25a834751 116 x &= 0xffffff80;\
wolfSSL 11:cee25a834751 117 x += 128; \
wolfSSL 11:cee25a834751 118 } \
wolfSSL 11:cee25a834751 119 } \
wolfSSL 11:cee25a834751 120 while (0)
wolfSSL 11:cee25a834751 121 #endif
wolfSSL 11:cee25a834751 122
wolfSSL 11:cee25a834751 123
wolfSSL 11:cee25a834751 124 static int GeneratePrivateDh(DhKey* key, WC_RNG* rng, byte* priv, word32* privSz)
wolfSSL 11:cee25a834751 125 {
wolfSSL 11:cee25a834751 126 int ret = 0;
wolfSSL 11:cee25a834751 127 word32 sz = mp_unsigned_bin_size(&key->p);
wolfSSL 11:cee25a834751 128
wolfSSL 11:cee25a834751 129 /* Table of predetermined values from the operation
wolfSSL 11:cee25a834751 130 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) / WOLFSSL_BIT_SIZE + 1
wolfSSL 11:cee25a834751 131 Sizes in table checked against RFC 3526
wolfSSL 11:cee25a834751 132 */
wolfSSL 11:cee25a834751 133 WOLFSSL_DH_ROUND(sz); /* if using fixed points only, then round up */
wolfSSL 11:cee25a834751 134 switch (sz) {
wolfSSL 11:cee25a834751 135 case 128: sz = 21; break;
wolfSSL 11:cee25a834751 136 case 256: sz = 29; break;
wolfSSL 11:cee25a834751 137 case 384: sz = 34; break;
wolfSSL 11:cee25a834751 138 case 512: sz = 39; break;
wolfSSL 11:cee25a834751 139 case 640: sz = 42; break;
wolfSSL 11:cee25a834751 140 case 768: sz = 46; break;
wolfSSL 11:cee25a834751 141 case 896: sz = 49; break;
wolfSSL 11:cee25a834751 142 case 1024: sz = 52; break;
wolfSSL 11:cee25a834751 143 default:
wolfSSL 11:cee25a834751 144 #ifndef WOLFSSL_DH_CONST
wolfSSL 11:cee25a834751 145 /* if using floating points and size of p is not in table */
wolfSSL 11:cee25a834751 146 sz = min(sz, 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) /
wolfSSL 11:cee25a834751 147 WOLFSSL_BIT_SIZE + 1);
wolfSSL 11:cee25a834751 148 break;
wolfSSL 11:cee25a834751 149 #else
wolfSSL 11:cee25a834751 150 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 151 #endif
wolfSSL 11:cee25a834751 152 }
wolfSSL 11:cee25a834751 153
wolfSSL 11:cee25a834751 154 ret = wc_RNG_GenerateBlock(rng, priv, sz);
wolfSSL 11:cee25a834751 155
wolfSSL 11:cee25a834751 156 if (ret == 0) {
wolfSSL 11:cee25a834751 157 priv[0] |= 0x0C;
wolfSSL 11:cee25a834751 158 *privSz = sz;
wolfSSL 11:cee25a834751 159 }
wolfSSL 11:cee25a834751 160
wolfSSL 11:cee25a834751 161 return ret;
wolfSSL 11:cee25a834751 162 }
wolfSSL 11:cee25a834751 163
wolfSSL 11:cee25a834751 164
wolfSSL 11:cee25a834751 165 static int GeneratePublicDh(DhKey* key, byte* priv, word32 privSz,
wolfSSL 11:cee25a834751 166 byte* pub, word32* pubSz)
wolfSSL 11:cee25a834751 167 {
wolfSSL 11:cee25a834751 168 int ret = 0;
wolfSSL 11:cee25a834751 169 mp_int x;
wolfSSL 11:cee25a834751 170 mp_int y;
wolfSSL 11:cee25a834751 171
wolfSSL 11:cee25a834751 172 if (mp_init_multi(&x, &y, 0, 0, 0, 0) != MP_OKAY)
wolfSSL 11:cee25a834751 173 return MP_INIT_E;
wolfSSL 11:cee25a834751 174
wolfSSL 11:cee25a834751 175 if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
wolfSSL 11:cee25a834751 176 ret = MP_READ_E;
wolfSSL 11:cee25a834751 177
wolfSSL 11:cee25a834751 178 if (ret == 0 && mp_exptmod(&key->g, &x, &key->p, &y) != MP_OKAY)
wolfSSL 11:cee25a834751 179 ret = MP_EXPTMOD_E;
wolfSSL 11:cee25a834751 180
wolfSSL 11:cee25a834751 181 if (ret == 0 && mp_to_unsigned_bin(&y, pub) != MP_OKAY)
wolfSSL 11:cee25a834751 182 ret = MP_TO_E;
wolfSSL 11:cee25a834751 183
wolfSSL 11:cee25a834751 184 if (ret == 0)
wolfSSL 11:cee25a834751 185 *pubSz = mp_unsigned_bin_size(&y);
wolfSSL 11:cee25a834751 186
wolfSSL 11:cee25a834751 187 mp_clear(&y);
wolfSSL 11:cee25a834751 188 mp_clear(&x);
wolfSSL 11:cee25a834751 189
wolfSSL 11:cee25a834751 190 return ret;
wolfSSL 11:cee25a834751 191 }
wolfSSL 11:cee25a834751 192
wolfSSL 11:cee25a834751 193 static int wc_DhGenerateKeyPair_Sync(DhKey* key, WC_RNG* rng,
wolfSSL 11:cee25a834751 194 byte* priv, word32* privSz, byte* pub, word32* pubSz)
wolfSSL 11:cee25a834751 195 {
wolfSSL 11:cee25a834751 196 int ret;
wolfSSL 11:cee25a834751 197
wolfSSL 11:cee25a834751 198 if (key == NULL || rng == NULL || priv == NULL || privSz == NULL ||
wolfSSL 11:cee25a834751 199 pub == NULL || pubSz == NULL) {
wolfSSL 11:cee25a834751 200 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 201 }
wolfSSL 11:cee25a834751 202
wolfSSL 11:cee25a834751 203 ret = GeneratePrivateDh(key, rng, priv, privSz);
wolfSSL 11:cee25a834751 204
wolfSSL 11:cee25a834751 205 return (ret != 0) ? ret : GeneratePublicDh(key, priv, *privSz, pub, pubSz);
wolfSSL 11:cee25a834751 206 }
wolfSSL 11:cee25a834751 207
wolfSSL 11:cee25a834751 208 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
wolfSSL 11:cee25a834751 209 static int wc_DhGenerateKeyPair_Async(DhKey* key, WC_RNG* rng,
wolfSSL 11:cee25a834751 210 byte* priv, word32* privSz, byte* pub, word32* pubSz)
wolfSSL 11:cee25a834751 211 {
wolfSSL 11:cee25a834751 212 int ret;
wolfSSL 11:cee25a834751 213
wolfSSL 11:cee25a834751 214 #if defined(HAVE_INTEL_QA)
wolfSSL 11:cee25a834751 215 mp_int x;
wolfSSL 11:cee25a834751 216
wolfSSL 11:cee25a834751 217 ret = mp_init(&x);
wolfSSL 11:cee25a834751 218 if (ret != MP_OKAY)
wolfSSL 11:cee25a834751 219 return ret;
wolfSSL 11:cee25a834751 220
wolfSSL 11:cee25a834751 221 ret = GeneratePrivateDh(key, rng, priv, privSz);
wolfSSL 11:cee25a834751 222 if (ret == 0)
wolfSSL 11:cee25a834751 223 ret = mp_read_unsigned_bin(&x, priv, *privSz);
wolfSSL 11:cee25a834751 224 if (ret == MP_OKAY)
wolfSSL 11:cee25a834751 225 ret = wc_mp_to_bigint(&x, &x.raw);
wolfSSL 11:cee25a834751 226 if (ret == MP_OKAY)
wolfSSL 11:cee25a834751 227 ret = wc_mp_to_bigint(&key->p, &key->p.raw);
wolfSSL 11:cee25a834751 228 if (ret == MP_OKAY)
wolfSSL 11:cee25a834751 229 ret = wc_mp_to_bigint(&key->g, &key->g.raw);
wolfSSL 11:cee25a834751 230 if (ret == MP_OKAY)
wolfSSL 11:cee25a834751 231 ret = IntelQaDhKeyGen(&key->asyncDev, &key->p.raw, &key->g.raw,
wolfSSL 11:cee25a834751 232 &x.raw, pub, pubSz);
wolfSSL 11:cee25a834751 233 mp_clear(&x);
wolfSSL 11:cee25a834751 234
wolfSSL 11:cee25a834751 235 #else
wolfSSL 11:cee25a834751 236
wolfSSL 11:cee25a834751 237 #if defined(HAVE_CAVIUM)
wolfSSL 11:cee25a834751 238 /* TODO: Not implemented - use software for now */
wolfSSL 11:cee25a834751 239
wolfSSL 11:cee25a834751 240 #else /* WOLFSSL_ASYNC_CRYPT_TEST */
wolfSSL 11:cee25a834751 241 WC_ASYNC_TEST* testDev = &key->asyncDev.test;
wolfSSL 11:cee25a834751 242 if (testDev->type == ASYNC_TEST_NONE) {
wolfSSL 11:cee25a834751 243 testDev->type = ASYNC_TEST_DH_GEN;
wolfSSL 11:cee25a834751 244 testDev->dhGen.key = key;
wolfSSL 11:cee25a834751 245 testDev->dhGen.rng = rng;
wolfSSL 11:cee25a834751 246 testDev->dhGen.priv = priv;
wolfSSL 11:cee25a834751 247 testDev->dhGen.privSz = privSz;
wolfSSL 11:cee25a834751 248 testDev->dhGen.pub = pub;
wolfSSL 11:cee25a834751 249 testDev->dhGen.pubSz = pubSz;
wolfSSL 11:cee25a834751 250 return WC_PENDING_E;
wolfSSL 11:cee25a834751 251 }
wolfSSL 11:cee25a834751 252 #endif
wolfSSL 11:cee25a834751 253
wolfSSL 11:cee25a834751 254 ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz);
wolfSSL 11:cee25a834751 255
wolfSSL 11:cee25a834751 256 #endif /* HAVE_INTEL_QA */
wolfSSL 11:cee25a834751 257
wolfSSL 11:cee25a834751 258 return ret;
wolfSSL 11:cee25a834751 259 }
wolfSSL 11:cee25a834751 260 #endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_DH */
wolfSSL 11:cee25a834751 261
wolfSSL 11:cee25a834751 262
wolfSSL 11:cee25a834751 263 /* Check DH Public Key for invalid numbers
wolfSSL 11:cee25a834751 264 *
wolfSSL 11:cee25a834751 265 * key DH key group parameters.
wolfSSL 11:cee25a834751 266 * pub Public Key.
wolfSSL 11:cee25a834751 267 * pubSz Public Key size.
wolfSSL 11:cee25a834751 268 *
wolfSSL 11:cee25a834751 269 * returns 0 on success or error code
wolfSSL 11:cee25a834751 270 */
wolfSSL 11:cee25a834751 271 int wc_DhCheckPubKey(DhKey* key, const byte* pub, word32 pubSz)
wolfSSL 11:cee25a834751 272 {
wolfSSL 11:cee25a834751 273 int ret = 0;
wolfSSL 11:cee25a834751 274
wolfSSL 11:cee25a834751 275 mp_int x;
wolfSSL 11:cee25a834751 276 mp_int y;
wolfSSL 11:cee25a834751 277
wolfSSL 11:cee25a834751 278 if (key == NULL || pub == NULL) {
wolfSSL 11:cee25a834751 279 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 280 }
wolfSSL 11:cee25a834751 281
wolfSSL 11:cee25a834751 282 if (mp_init_multi(&x, &y, NULL, NULL, NULL, NULL) != MP_OKAY) {
wolfSSL 11:cee25a834751 283 return MP_INIT_E;
wolfSSL 11:cee25a834751 284 }
wolfSSL 11:cee25a834751 285
wolfSSL 11:cee25a834751 286 if (mp_read_unsigned_bin(&x, pub, pubSz) != MP_OKAY) {
wolfSSL 11:cee25a834751 287 ret = MP_READ_E;
wolfSSL 11:cee25a834751 288 }
wolfSSL 11:cee25a834751 289
wolfSSL 11:cee25a834751 290 /* pub should not be 0 or 1 */
wolfSSL 11:cee25a834751 291 if (ret == 0 && mp_cmp_d(&x, 2) == MP_LT) {
wolfSSL 11:cee25a834751 292 ret = MP_CMP_E;
wolfSSL 11:cee25a834751 293 }
wolfSSL 11:cee25a834751 294
wolfSSL 11:cee25a834751 295 /* pub shouldn't be greater than or equal to p - 1 */
wolfSSL 11:cee25a834751 296 if (ret == 0 && mp_copy(&key->p, &y) != MP_OKAY) {
wolfSSL 11:cee25a834751 297 ret = MP_INIT_E;
wolfSSL 11:cee25a834751 298 }
wolfSSL 11:cee25a834751 299 if (ret == 0 && mp_sub_d(&y, 2, &y) != MP_OKAY) {
wolfSSL 11:cee25a834751 300 ret = MP_SUB_E;
wolfSSL 11:cee25a834751 301 }
wolfSSL 11:cee25a834751 302 if (ret == 0 && mp_cmp(&x, &y) == MP_GT) {
wolfSSL 11:cee25a834751 303 ret = MP_CMP_E;
wolfSSL 11:cee25a834751 304 }
wolfSSL 11:cee25a834751 305
wolfSSL 11:cee25a834751 306 mp_clear(&y);
wolfSSL 11:cee25a834751 307 mp_clear(&x);
wolfSSL 11:cee25a834751 308
wolfSSL 11:cee25a834751 309 return ret;
wolfSSL 11:cee25a834751 310 }
wolfSSL 11:cee25a834751 311
wolfSSL 11:cee25a834751 312
wolfSSL 11:cee25a834751 313 int wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng,
wolfSSL 11:cee25a834751 314 byte* priv, word32* privSz, byte* pub, word32* pubSz)
wolfSSL 11:cee25a834751 315 {
wolfSSL 11:cee25a834751 316 int ret;
wolfSSL 11:cee25a834751 317
wolfSSL 11:cee25a834751 318 if (key == NULL || rng == NULL || priv == NULL || privSz == NULL ||
wolfSSL 11:cee25a834751 319 pub == NULL || pubSz == NULL) {
wolfSSL 11:cee25a834751 320 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 321 }
wolfSSL 11:cee25a834751 322
wolfSSL 11:cee25a834751 323 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
wolfSSL 11:cee25a834751 324 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_DH) {
wolfSSL 11:cee25a834751 325 ret = wc_DhGenerateKeyPair_Async(key, rng, priv, privSz, pub, pubSz);
wolfSSL 11:cee25a834751 326 }
wolfSSL 11:cee25a834751 327 else
wolfSSL 11:cee25a834751 328 #endif
wolfSSL 11:cee25a834751 329 {
wolfSSL 11:cee25a834751 330 ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz);
wolfSSL 11:cee25a834751 331 }
wolfSSL 11:cee25a834751 332
wolfSSL 11:cee25a834751 333 return ret;
wolfSSL 11:cee25a834751 334 }
wolfSSL 11:cee25a834751 335
wolfSSL 11:cee25a834751 336
wolfSSL 11:cee25a834751 337 static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
wolfSSL 11:cee25a834751 338 const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz)
wolfSSL 11:cee25a834751 339 {
wolfSSL 11:cee25a834751 340 int ret = 0;
wolfSSL 11:cee25a834751 341 mp_int x;
wolfSSL 11:cee25a834751 342 mp_int y;
wolfSSL 11:cee25a834751 343 mp_int z;
wolfSSL 11:cee25a834751 344
wolfSSL 11:cee25a834751 345 if (wc_DhCheckPubKey(key, otherPub, pubSz) != 0) {
wolfSSL 11:cee25a834751 346 WOLFSSL_MSG("wc_DhAgree wc_DhCheckPubKey failed");
wolfSSL 11:cee25a834751 347 return DH_CHECK_PUB_E;
wolfSSL 11:cee25a834751 348 }
wolfSSL 11:cee25a834751 349
wolfSSL 11:cee25a834751 350 if (mp_init_multi(&x, &y, &z, 0, 0, 0) != MP_OKAY)
wolfSSL 11:cee25a834751 351 return MP_INIT_E;
wolfSSL 11:cee25a834751 352
wolfSSL 11:cee25a834751 353 if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
wolfSSL 11:cee25a834751 354 ret = MP_READ_E;
wolfSSL 11:cee25a834751 355
wolfSSL 11:cee25a834751 356 if (ret == 0 && mp_read_unsigned_bin(&y, otherPub, pubSz) != MP_OKAY)
wolfSSL 11:cee25a834751 357 ret = MP_READ_E;
wolfSSL 11:cee25a834751 358
wolfSSL 11:cee25a834751 359 if (ret == 0 && mp_exptmod(&y, &x, &key->p, &z) != MP_OKAY)
wolfSSL 11:cee25a834751 360 ret = MP_EXPTMOD_E;
wolfSSL 11:cee25a834751 361
wolfSSL 11:cee25a834751 362 if (ret == 0 && mp_to_unsigned_bin(&z, agree) != MP_OKAY)
wolfSSL 11:cee25a834751 363 ret = MP_TO_E;
wolfSSL 11:cee25a834751 364
wolfSSL 11:cee25a834751 365 if (ret == 0)
wolfSSL 11:cee25a834751 366 *agreeSz = mp_unsigned_bin_size(&z);
wolfSSL 11:cee25a834751 367
wolfSSL 11:cee25a834751 368 mp_clear(&z);
wolfSSL 11:cee25a834751 369 mp_clear(&y);
wolfSSL 11:cee25a834751 370 mp_forcezero(&x);
wolfSSL 11:cee25a834751 371
wolfSSL 11:cee25a834751 372 return ret;
wolfSSL 11:cee25a834751 373 }
wolfSSL 11:cee25a834751 374
wolfSSL 11:cee25a834751 375 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
wolfSSL 11:cee25a834751 376 static int wc_DhAgree_Async(DhKey* key, byte* agree, word32* agreeSz,
wolfSSL 11:cee25a834751 377 const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz)
wolfSSL 11:cee25a834751 378 {
wolfSSL 11:cee25a834751 379 int ret;
wolfSSL 11:cee25a834751 380
wolfSSL 11:cee25a834751 381 #ifdef HAVE_CAVIUM
wolfSSL 11:cee25a834751 382 /* TODO: Not implemented - use software for now */
wolfSSL 11:cee25a834751 383 ret = wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub, pubSz);
wolfSSL 11:cee25a834751 384
wolfSSL 11:cee25a834751 385 #elif defined(HAVE_INTEL_QA)
wolfSSL 11:cee25a834751 386 ret = wc_mp_to_bigint(&key->p, &key->p.raw);
wolfSSL 11:cee25a834751 387 if (ret == MP_OKAY)
wolfSSL 11:cee25a834751 388 ret = IntelQaDhAgree(&key->asyncDev, &key->p.raw,
wolfSSL 11:cee25a834751 389 agree, agreeSz, priv, privSz, otherPub, pubSz);
wolfSSL 11:cee25a834751 390 #else /* WOLFSSL_ASYNC_CRYPT_TEST */
wolfSSL 11:cee25a834751 391 WC_ASYNC_TEST* testDev = &key->asyncDev.test;
wolfSSL 11:cee25a834751 392 if (testDev->type == ASYNC_TEST_NONE) {
wolfSSL 11:cee25a834751 393 testDev->type = ASYNC_TEST_DH_AGREE;
wolfSSL 11:cee25a834751 394 testDev->dhAgree.key = key;
wolfSSL 11:cee25a834751 395 testDev->dhAgree.agree = agree;
wolfSSL 11:cee25a834751 396 testDev->dhAgree.agreeSz = agreeSz;
wolfSSL 11:cee25a834751 397 testDev->dhAgree.priv = priv;
wolfSSL 11:cee25a834751 398 testDev->dhAgree.privSz = privSz;
wolfSSL 11:cee25a834751 399 testDev->dhAgree.otherPub = otherPub;
wolfSSL 11:cee25a834751 400 testDev->dhAgree.pubSz = pubSz;
wolfSSL 11:cee25a834751 401 return WC_PENDING_E;
wolfSSL 11:cee25a834751 402 }
wolfSSL 11:cee25a834751 403 ret = wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub, pubSz);
wolfSSL 11:cee25a834751 404 #endif
wolfSSL 11:cee25a834751 405
wolfSSL 11:cee25a834751 406 return ret;
wolfSSL 11:cee25a834751 407 }
wolfSSL 11:cee25a834751 408 #endif /* WOLFSSL_ASYNC_CRYPT */
wolfSSL 11:cee25a834751 409
wolfSSL 11:cee25a834751 410 int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
wolfSSL 11:cee25a834751 411 word32 privSz, const byte* otherPub, word32 pubSz)
wolfSSL 11:cee25a834751 412 {
wolfSSL 11:cee25a834751 413 int ret = 0;
wolfSSL 11:cee25a834751 414
wolfSSL 11:cee25a834751 415 if (key == NULL || agree == NULL || agreeSz == NULL || priv == NULL ||
wolfSSL 11:cee25a834751 416 otherPub == NULL) {
wolfSSL 11:cee25a834751 417 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 418 }
wolfSSL 11:cee25a834751 419
wolfSSL 11:cee25a834751 420 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
wolfSSL 11:cee25a834751 421 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_DH) {
wolfSSL 11:cee25a834751 422 ret = wc_DhAgree_Async(key, agree, agreeSz, priv, privSz, otherPub, pubSz);
wolfSSL 11:cee25a834751 423 }
wolfSSL 11:cee25a834751 424 else
wolfSSL 11:cee25a834751 425 #endif
wolfSSL 11:cee25a834751 426 {
wolfSSL 11:cee25a834751 427 ret = wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub, pubSz);
wolfSSL 11:cee25a834751 428 }
wolfSSL 11:cee25a834751 429
wolfSSL 11:cee25a834751 430 return ret;
wolfSSL 11:cee25a834751 431 }
wolfSSL 11:cee25a834751 432
wolfSSL 11:cee25a834751 433
wolfSSL 11:cee25a834751 434 /* not in asn anymore since no actual asn types used */
wolfSSL 11:cee25a834751 435 int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
wolfSSL 11:cee25a834751 436 word32 gSz)
wolfSSL 11:cee25a834751 437 {
wolfSSL 11:cee25a834751 438 if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0) {
wolfSSL 11:cee25a834751 439 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 440 }
wolfSSL 11:cee25a834751 441
wolfSSL 11:cee25a834751 442 /* may have leading 0 */
wolfSSL 11:cee25a834751 443 if (p[0] == 0) {
wolfSSL 11:cee25a834751 444 pSz--; p++;
wolfSSL 11:cee25a834751 445 }
wolfSSL 11:cee25a834751 446
wolfSSL 11:cee25a834751 447 if (g[0] == 0) {
wolfSSL 11:cee25a834751 448 gSz--; g++;
wolfSSL 11:cee25a834751 449 }
wolfSSL 11:cee25a834751 450
wolfSSL 11:cee25a834751 451 if (mp_init(&key->p) != MP_OKAY)
wolfSSL 11:cee25a834751 452 return MP_INIT_E;
wolfSSL 11:cee25a834751 453 if (mp_read_unsigned_bin(&key->p, p, pSz) != 0) {
wolfSSL 11:cee25a834751 454 mp_clear(&key->p);
wolfSSL 11:cee25a834751 455 return ASN_DH_KEY_E;
wolfSSL 11:cee25a834751 456 }
wolfSSL 11:cee25a834751 457
wolfSSL 11:cee25a834751 458 if (mp_init(&key->g) != MP_OKAY) {
wolfSSL 11:cee25a834751 459 mp_clear(&key->p);
wolfSSL 11:cee25a834751 460 return MP_INIT_E;
wolfSSL 11:cee25a834751 461 }
wolfSSL 11:cee25a834751 462 if (mp_read_unsigned_bin(&key->g, g, gSz) != 0) {
wolfSSL 11:cee25a834751 463 mp_clear(&key->g);
wolfSSL 11:cee25a834751 464 mp_clear(&key->p);
wolfSSL 11:cee25a834751 465 return ASN_DH_KEY_E;
wolfSSL 11:cee25a834751 466 }
wolfSSL 11:cee25a834751 467
wolfSSL 11:cee25a834751 468 return 0;
wolfSSL 11:cee25a834751 469 }
wolfSSL 11:cee25a834751 470
wolfSSL 11:cee25a834751 471 #endif /* NO_DH */
wolfSSL 11:cee25a834751 472