wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

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 /* srp.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 #ifdef WOLFCRYPT_HAVE_SRP
wolfSSL 7:481bce714567 30
wolfSSL 7:481bce714567 31 #include <wolfssl/wolfcrypt/srp.h>
wolfSSL 7:481bce714567 32 #include <wolfssl/wolfcrypt/random.h>
wolfSSL 7:481bce714567 33 #include <wolfssl/wolfcrypt/error-crypt.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 /** Computes the session key using the Mask Generation Function 1. */
wolfSSL 7:481bce714567 43 static int wc_SrpSetKey(Srp* srp, byte* secret, word32 size);
wolfSSL 7:481bce714567 44
wolfSSL 7:481bce714567 45 static int SrpHashInit(SrpHash* hash, SrpType type)
wolfSSL 7:481bce714567 46 {
wolfSSL 7:481bce714567 47 hash->type = type;
wolfSSL 7:481bce714567 48
wolfSSL 7:481bce714567 49 switch (type) {
wolfSSL 7:481bce714567 50 case SRP_TYPE_SHA:
wolfSSL 7:481bce714567 51 #ifndef NO_SHA
wolfSSL 7:481bce714567 52 return wc_InitSha(&hash->data.sha);
wolfSSL 7:481bce714567 53 #else
wolfSSL 7:481bce714567 54 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 55 #endif
wolfSSL 7:481bce714567 56
wolfSSL 7:481bce714567 57 case SRP_TYPE_SHA256:
wolfSSL 7:481bce714567 58 #ifndef NO_SHA256
wolfSSL 7:481bce714567 59 return wc_InitSha256(&hash->data.sha256);
wolfSSL 7:481bce714567 60 #else
wolfSSL 7:481bce714567 61 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 62 #endif
wolfSSL 7:481bce714567 63
wolfSSL 7:481bce714567 64 case SRP_TYPE_SHA384:
wolfSSL 7:481bce714567 65 #ifdef WOLFSSL_SHA384
wolfSSL 7:481bce714567 66 return wc_InitSha384(&hash->data.sha384);
wolfSSL 7:481bce714567 67 #else
wolfSSL 7:481bce714567 68 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 69 #endif
wolfSSL 7:481bce714567 70
wolfSSL 7:481bce714567 71 case SRP_TYPE_SHA512:
wolfSSL 7:481bce714567 72 #ifdef WOLFSSL_SHA512
wolfSSL 7:481bce714567 73 return wc_InitSha512(&hash->data.sha512);
wolfSSL 7:481bce714567 74 #else
wolfSSL 7:481bce714567 75 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 76 #endif
wolfSSL 7:481bce714567 77
wolfSSL 7:481bce714567 78 default:
wolfSSL 7:481bce714567 79 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 80 }
wolfSSL 7:481bce714567 81 }
wolfSSL 7:481bce714567 82
wolfSSL 7:481bce714567 83 static int SrpHashUpdate(SrpHash* hash, const byte* data, word32 size)
wolfSSL 7:481bce714567 84 {
wolfSSL 7:481bce714567 85 switch (hash->type) {
wolfSSL 7:481bce714567 86 case SRP_TYPE_SHA:
wolfSSL 7:481bce714567 87 #ifndef NO_SHA
wolfSSL 7:481bce714567 88 return wc_ShaUpdate(&hash->data.sha, data, size);
wolfSSL 7:481bce714567 89 #else
wolfSSL 7:481bce714567 90 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 91 #endif
wolfSSL 7:481bce714567 92
wolfSSL 7:481bce714567 93 case SRP_TYPE_SHA256:
wolfSSL 7:481bce714567 94 #ifndef NO_SHA256
wolfSSL 7:481bce714567 95 return wc_Sha256Update(&hash->data.sha256, data, size);
wolfSSL 7:481bce714567 96 #else
wolfSSL 7:481bce714567 97 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 98 #endif
wolfSSL 7:481bce714567 99
wolfSSL 7:481bce714567 100 case SRP_TYPE_SHA384:
wolfSSL 7:481bce714567 101 #ifdef WOLFSSL_SHA384
wolfSSL 7:481bce714567 102 return wc_Sha384Update(&hash->data.sha384, data, size);
wolfSSL 7:481bce714567 103 #else
wolfSSL 7:481bce714567 104 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 105 #endif
wolfSSL 7:481bce714567 106
wolfSSL 7:481bce714567 107 case SRP_TYPE_SHA512:
wolfSSL 7:481bce714567 108 #ifdef WOLFSSL_SHA512
wolfSSL 7:481bce714567 109 return wc_Sha512Update(&hash->data.sha512, data, size);
wolfSSL 7:481bce714567 110 #else
wolfSSL 7:481bce714567 111 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 112 #endif
wolfSSL 7:481bce714567 113
wolfSSL 7:481bce714567 114 default:
wolfSSL 7:481bce714567 115 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 116 }
wolfSSL 7:481bce714567 117 }
wolfSSL 7:481bce714567 118
wolfSSL 7:481bce714567 119 static int SrpHashFinal(SrpHash* hash, byte* digest)
wolfSSL 7:481bce714567 120 {
wolfSSL 7:481bce714567 121 switch (hash->type) {
wolfSSL 7:481bce714567 122 case SRP_TYPE_SHA:
wolfSSL 7:481bce714567 123 #ifndef NO_SHA
wolfSSL 7:481bce714567 124 return wc_ShaFinal(&hash->data.sha, digest);
wolfSSL 7:481bce714567 125 #else
wolfSSL 7:481bce714567 126 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 127 #endif
wolfSSL 7:481bce714567 128
wolfSSL 7:481bce714567 129 case SRP_TYPE_SHA256:
wolfSSL 7:481bce714567 130 #ifndef NO_SHA256
wolfSSL 7:481bce714567 131 return wc_Sha256Final(&hash->data.sha256, digest);
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 case SRP_TYPE_SHA384:
wolfSSL 7:481bce714567 137 #ifdef WOLFSSL_SHA384
wolfSSL 7:481bce714567 138 return wc_Sha384Final(&hash->data.sha384, digest);
wolfSSL 7:481bce714567 139 #else
wolfSSL 7:481bce714567 140 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 141 #endif
wolfSSL 7:481bce714567 142
wolfSSL 7:481bce714567 143 case SRP_TYPE_SHA512:
wolfSSL 7:481bce714567 144 #ifdef WOLFSSL_SHA512
wolfSSL 7:481bce714567 145 return wc_Sha512Final(&hash->data.sha512, digest);
wolfSSL 7:481bce714567 146 #else
wolfSSL 7:481bce714567 147 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 148 #endif
wolfSSL 7:481bce714567 149
wolfSSL 7:481bce714567 150 default:
wolfSSL 7:481bce714567 151 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 152 }
wolfSSL 7:481bce714567 153 }
wolfSSL 7:481bce714567 154
wolfSSL 7:481bce714567 155 static word32 SrpHashSize(SrpType type)
wolfSSL 7:481bce714567 156 {
wolfSSL 7:481bce714567 157 switch (type) {
wolfSSL 7:481bce714567 158 case SRP_TYPE_SHA:
wolfSSL 7:481bce714567 159 #ifndef NO_SHA
wolfSSL 7:481bce714567 160 return SHA_DIGEST_SIZE;
wolfSSL 7:481bce714567 161 #else
wolfSSL 7:481bce714567 162 return 0;
wolfSSL 7:481bce714567 163 #endif
wolfSSL 7:481bce714567 164
wolfSSL 7:481bce714567 165 case SRP_TYPE_SHA256:
wolfSSL 7:481bce714567 166 #ifndef NO_SHA256
wolfSSL 7:481bce714567 167 return SHA256_DIGEST_SIZE;
wolfSSL 7:481bce714567 168 #else
wolfSSL 7:481bce714567 169 return 0;
wolfSSL 7:481bce714567 170 #endif
wolfSSL 7:481bce714567 171
wolfSSL 7:481bce714567 172 case SRP_TYPE_SHA384:
wolfSSL 7:481bce714567 173 #ifdef WOLFSSL_SHA384
wolfSSL 7:481bce714567 174 return SHA384_DIGEST_SIZE;
wolfSSL 7:481bce714567 175 #else
wolfSSL 7:481bce714567 176 return 0;
wolfSSL 7:481bce714567 177 #endif
wolfSSL 7:481bce714567 178
wolfSSL 7:481bce714567 179 case SRP_TYPE_SHA512:
wolfSSL 7:481bce714567 180 #ifdef WOLFSSL_SHA512
wolfSSL 7:481bce714567 181 return SHA512_DIGEST_SIZE;
wolfSSL 7:481bce714567 182 #else
wolfSSL 7:481bce714567 183 return 0;
wolfSSL 7:481bce714567 184 #endif
wolfSSL 7:481bce714567 185
wolfSSL 7:481bce714567 186 default:
wolfSSL 7:481bce714567 187 return 0;
wolfSSL 7:481bce714567 188 }
wolfSSL 7:481bce714567 189 }
wolfSSL 7:481bce714567 190
wolfSSL 7:481bce714567 191 int wc_SrpInit(Srp* srp, SrpType type, SrpSide side)
wolfSSL 7:481bce714567 192 {
wolfSSL 7:481bce714567 193 int r;
wolfSSL 7:481bce714567 194
wolfSSL 7:481bce714567 195 /* validating params */
wolfSSL 7:481bce714567 196
wolfSSL 7:481bce714567 197 if (!srp)
wolfSSL 7:481bce714567 198 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 199
wolfSSL 7:481bce714567 200 if (side != SRP_CLIENT_SIDE && side != SRP_SERVER_SIDE)
wolfSSL 7:481bce714567 201 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 202
wolfSSL 7:481bce714567 203 switch (type) {
wolfSSL 7:481bce714567 204 case SRP_TYPE_SHA:
wolfSSL 7:481bce714567 205 #ifdef NO_SHA
wolfSSL 7:481bce714567 206 return NOT_COMPILED_IN;
wolfSSL 7:481bce714567 207 #else
wolfSSL 7:481bce714567 208 break; /* OK */
wolfSSL 7:481bce714567 209 #endif
wolfSSL 7:481bce714567 210
wolfSSL 7:481bce714567 211 case SRP_TYPE_SHA256:
wolfSSL 7:481bce714567 212 #ifdef NO_SHA256
wolfSSL 7:481bce714567 213 return NOT_COMPILED_IN;
wolfSSL 7:481bce714567 214 #else
wolfSSL 7:481bce714567 215 break; /* OK */
wolfSSL 7:481bce714567 216 #endif
wolfSSL 7:481bce714567 217
wolfSSL 7:481bce714567 218 case SRP_TYPE_SHA384:
wolfSSL 7:481bce714567 219 #ifndef WOLFSSL_SHA384
wolfSSL 7:481bce714567 220 return NOT_COMPILED_IN;
wolfSSL 7:481bce714567 221 #else
wolfSSL 7:481bce714567 222 break; /* OK */
wolfSSL 7:481bce714567 223 #endif
wolfSSL 7:481bce714567 224
wolfSSL 7:481bce714567 225 case SRP_TYPE_SHA512:
wolfSSL 7:481bce714567 226 #ifndef WOLFSSL_SHA512
wolfSSL 7:481bce714567 227 return NOT_COMPILED_IN;
wolfSSL 7:481bce714567 228 #else
wolfSSL 7:481bce714567 229 break; /* OK */
wolfSSL 7:481bce714567 230 #endif
wolfSSL 7:481bce714567 231
wolfSSL 7:481bce714567 232 default:
wolfSSL 7:481bce714567 233 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 234 }
wolfSSL 7:481bce714567 235
wolfSSL 7:481bce714567 236 /* initializing variables */
wolfSSL 7:481bce714567 237
wolfSSL 7:481bce714567 238 XMEMSET(srp, 0, sizeof(Srp));
wolfSSL 7:481bce714567 239
wolfSSL 7:481bce714567 240 if ((r = SrpHashInit(&srp->client_proof, type)) != 0)
wolfSSL 7:481bce714567 241 return r;
wolfSSL 7:481bce714567 242
wolfSSL 7:481bce714567 243 if ((r = SrpHashInit(&srp->server_proof, type)) != 0)
wolfSSL 7:481bce714567 244 return r;
wolfSSL 7:481bce714567 245
wolfSSL 7:481bce714567 246 if ((r = mp_init_multi(&srp->N, &srp->g, &srp->auth,
wolfSSL 7:481bce714567 247 &srp->priv, 0, 0)) != 0)
wolfSSL 7:481bce714567 248 return r;
wolfSSL 7:481bce714567 249
wolfSSL 7:481bce714567 250 srp->side = side; srp->type = type;
wolfSSL 7:481bce714567 251 srp->salt = NULL; srp->saltSz = 0;
wolfSSL 7:481bce714567 252 srp->user = NULL; srp->userSz = 0;
wolfSSL 7:481bce714567 253 srp->key = NULL; srp->keySz = 0;
wolfSSL 7:481bce714567 254
wolfSSL 7:481bce714567 255 srp->keyGenFunc_cb = wc_SrpSetKey;
wolfSSL 7:481bce714567 256
wolfSSL 7:481bce714567 257 /* default heap hint to NULL or test value */
wolfSSL 7:481bce714567 258 #ifdef WOLFSSL_HEAP_TEST
wolfSSL 7:481bce714567 259 srp->heap = (void*)WOLFSSL_HEAP_TEST;
wolfSSL 7:481bce714567 260 #else
wolfSSL 7:481bce714567 261 srp->heap = NULL;
wolfSSL 7:481bce714567 262 #endif
wolfSSL 7:481bce714567 263
wolfSSL 7:481bce714567 264 return 0;
wolfSSL 7:481bce714567 265 }
wolfSSL 7:481bce714567 266
wolfSSL 7:481bce714567 267 void wc_SrpTerm(Srp* srp)
wolfSSL 7:481bce714567 268 {
wolfSSL 7:481bce714567 269 if (srp) {
wolfSSL 7:481bce714567 270 mp_clear(&srp->N); mp_clear(&srp->g);
wolfSSL 7:481bce714567 271 mp_clear(&srp->auth); mp_clear(&srp->priv);
wolfSSL 7:481bce714567 272
wolfSSL 7:481bce714567 273 if (srp->salt) {
wolfSSL 7:481bce714567 274 ForceZero(srp->salt, srp->saltSz);
wolfSSL 7:481bce714567 275 XFREE(srp->salt, srp->heap, DYNAMIC_TYPE_SRP);
wolfSSL 7:481bce714567 276 }
wolfSSL 7:481bce714567 277 if (srp->user) {
wolfSSL 7:481bce714567 278 ForceZero(srp->user, srp->userSz);
wolfSSL 7:481bce714567 279 XFREE(srp->user, srp->heap, DYNAMIC_TYPE_SRP);
wolfSSL 7:481bce714567 280 }
wolfSSL 7:481bce714567 281 if (srp->key) {
wolfSSL 7:481bce714567 282 ForceZero(srp->key, srp->keySz);
wolfSSL 7:481bce714567 283 XFREE(srp->key, srp->heap, DYNAMIC_TYPE_SRP);
wolfSSL 7:481bce714567 284 }
wolfSSL 7:481bce714567 285
wolfSSL 7:481bce714567 286 ForceZero(srp, sizeof(Srp));
wolfSSL 7:481bce714567 287 }
wolfSSL 7:481bce714567 288 }
wolfSSL 7:481bce714567 289
wolfSSL 7:481bce714567 290 int wc_SrpSetUsername(Srp* srp, const byte* username, word32 size)
wolfSSL 7:481bce714567 291 {
wolfSSL 7:481bce714567 292 if (!srp || !username)
wolfSSL 7:481bce714567 293 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 294
wolfSSL 7:481bce714567 295 srp->user = (byte*)XMALLOC(size, srp->heap, DYNAMIC_TYPE_SRP);
wolfSSL 7:481bce714567 296 if (srp->user == NULL)
wolfSSL 7:481bce714567 297 return MEMORY_E;
wolfSSL 7:481bce714567 298
wolfSSL 7:481bce714567 299 srp->userSz = size;
wolfSSL 7:481bce714567 300 XMEMCPY(srp->user, username, srp->userSz);
wolfSSL 7:481bce714567 301
wolfSSL 7:481bce714567 302 return 0;
wolfSSL 7:481bce714567 303 }
wolfSSL 7:481bce714567 304
wolfSSL 7:481bce714567 305 int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz,
wolfSSL 7:481bce714567 306 const byte* g, word32 gSz,
wolfSSL 7:481bce714567 307 const byte* salt, word32 saltSz)
wolfSSL 7:481bce714567 308 {
wolfSSL 7:481bce714567 309 SrpHash hash;
wolfSSL 7:481bce714567 310 byte digest1[SRP_MAX_DIGEST_SIZE];
wolfSSL 7:481bce714567 311 byte digest2[SRP_MAX_DIGEST_SIZE];
wolfSSL 7:481bce714567 312 byte pad = 0;
wolfSSL 7:481bce714567 313 int i, r;
wolfSSL 7:481bce714567 314 int j = 0;
wolfSSL 7:481bce714567 315
wolfSSL 7:481bce714567 316 if (!srp || !N || !g || !salt || nSz < gSz)
wolfSSL 7:481bce714567 317 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 318
wolfSSL 7:481bce714567 319 if (!srp->user)
wolfSSL 7:481bce714567 320 return SRP_CALL_ORDER_E;
wolfSSL 7:481bce714567 321
wolfSSL 7:481bce714567 322 /* Set N */
wolfSSL 7:481bce714567 323 if (mp_read_unsigned_bin(&srp->N, N, nSz) != MP_OKAY)
wolfSSL 7:481bce714567 324 return MP_READ_E;
wolfSSL 7:481bce714567 325
wolfSSL 7:481bce714567 326 if (mp_count_bits(&srp->N) < SRP_MODULUS_MIN_BITS)
wolfSSL 7:481bce714567 327 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 328
wolfSSL 7:481bce714567 329 /* Set g */
wolfSSL 7:481bce714567 330 if (mp_read_unsigned_bin(&srp->g, g, gSz) != MP_OKAY)
wolfSSL 7:481bce714567 331 return MP_READ_E;
wolfSSL 7:481bce714567 332
wolfSSL 7:481bce714567 333 if (mp_cmp(&srp->N, &srp->g) != MP_GT)
wolfSSL 7:481bce714567 334 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 335
wolfSSL 7:481bce714567 336 /* Set salt */
wolfSSL 7:481bce714567 337 if (srp->salt) {
wolfSSL 7:481bce714567 338 ForceZero(srp->salt, srp->saltSz);
wolfSSL 7:481bce714567 339 XFREE(srp->salt, srp->heap, DYNAMIC_TYPE_SRP);
wolfSSL 7:481bce714567 340 }
wolfSSL 7:481bce714567 341
wolfSSL 7:481bce714567 342 srp->salt = (byte*)XMALLOC(saltSz, srp->heap, DYNAMIC_TYPE_SRP);
wolfSSL 7:481bce714567 343 if (srp->salt == NULL)
wolfSSL 7:481bce714567 344 return MEMORY_E;
wolfSSL 7:481bce714567 345
wolfSSL 7:481bce714567 346 XMEMCPY(srp->salt, salt, saltSz);
wolfSSL 7:481bce714567 347 srp->saltSz = saltSz;
wolfSSL 7:481bce714567 348
wolfSSL 7:481bce714567 349 /* Set k = H(N, g) */
wolfSSL 7:481bce714567 350 r = SrpHashInit(&hash, srp->type);
wolfSSL 7:481bce714567 351 if (!r) r = SrpHashUpdate(&hash, (byte*) N, nSz);
wolfSSL 7:481bce714567 352 for (i = 0; (word32)i < nSz - gSz; i++)
wolfSSL 7:481bce714567 353 SrpHashUpdate(&hash, &pad, 1);
wolfSSL 7:481bce714567 354 if (!r) r = SrpHashUpdate(&hash, (byte*) g, gSz);
wolfSSL 7:481bce714567 355 if (!r) r = SrpHashFinal(&hash, srp->k);
wolfSSL 7:481bce714567 356
wolfSSL 7:481bce714567 357 /* update client proof */
wolfSSL 7:481bce714567 358
wolfSSL 7:481bce714567 359 /* digest1 = H(N) */
wolfSSL 7:481bce714567 360 if (!r) r = SrpHashInit(&hash, srp->type);
wolfSSL 7:481bce714567 361 if (!r) r = SrpHashUpdate(&hash, (byte*) N, nSz);
wolfSSL 7:481bce714567 362 if (!r) r = SrpHashFinal(&hash, digest1);
wolfSSL 7:481bce714567 363
wolfSSL 7:481bce714567 364 /* digest2 = H(g) */
wolfSSL 7:481bce714567 365 if (!r) r = SrpHashInit(&hash, srp->type);
wolfSSL 7:481bce714567 366 if (!r) r = SrpHashUpdate(&hash, (byte*) g, gSz);
wolfSSL 7:481bce714567 367 if (!r) r = SrpHashFinal(&hash, digest2);
wolfSSL 7:481bce714567 368
wolfSSL 7:481bce714567 369 /* digest1 = H(N) ^ H(g) */
wolfSSL 7:481bce714567 370 if (r == 0) {
wolfSSL 7:481bce714567 371 for (i = 0, j = SrpHashSize(srp->type); i < j; i++)
wolfSSL 7:481bce714567 372 digest1[i] ^= digest2[i];
wolfSSL 7:481bce714567 373 }
wolfSSL 7:481bce714567 374
wolfSSL 7:481bce714567 375 /* digest2 = H(user) */
wolfSSL 7:481bce714567 376 if (!r) r = SrpHashInit(&hash, srp->type);
wolfSSL 7:481bce714567 377 if (!r) r = SrpHashUpdate(&hash, srp->user, srp->userSz);
wolfSSL 7:481bce714567 378 if (!r) r = SrpHashFinal(&hash, digest2);
wolfSSL 7:481bce714567 379
wolfSSL 7:481bce714567 380 /* client proof = H( H(N) ^ H(g) | H(user) | salt) */
wolfSSL 7:481bce714567 381 if (!r) r = SrpHashUpdate(&srp->client_proof, digest1, j);
wolfSSL 7:481bce714567 382 if (!r) r = SrpHashUpdate(&srp->client_proof, digest2, j);
wolfSSL 7:481bce714567 383 if (!r) r = SrpHashUpdate(&srp->client_proof, salt, saltSz);
wolfSSL 7:481bce714567 384
wolfSSL 7:481bce714567 385 return r;
wolfSSL 7:481bce714567 386 }
wolfSSL 7:481bce714567 387
wolfSSL 7:481bce714567 388 int wc_SrpSetPassword(Srp* srp, const byte* password, word32 size)
wolfSSL 7:481bce714567 389 {
wolfSSL 7:481bce714567 390 SrpHash hash;
wolfSSL 7:481bce714567 391 byte digest[SRP_MAX_DIGEST_SIZE];
wolfSSL 7:481bce714567 392 word32 digestSz;
wolfSSL 7:481bce714567 393 int r;
wolfSSL 7:481bce714567 394
wolfSSL 7:481bce714567 395 if (!srp || !password || srp->side != SRP_CLIENT_SIDE)
wolfSSL 7:481bce714567 396 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 397
wolfSSL 7:481bce714567 398 if (!srp->salt)
wolfSSL 7:481bce714567 399 return SRP_CALL_ORDER_E;
wolfSSL 7:481bce714567 400
wolfSSL 7:481bce714567 401 digestSz = SrpHashSize(srp->type);
wolfSSL 7:481bce714567 402
wolfSSL 7:481bce714567 403 /* digest = H(username | ':' | password) */
wolfSSL 7:481bce714567 404 r = SrpHashInit(&hash, srp->type);
wolfSSL 7:481bce714567 405 if (!r) r = SrpHashUpdate(&hash, srp->user, srp->userSz);
wolfSSL 7:481bce714567 406 if (!r) r = SrpHashUpdate(&hash, (const byte*) ":", 1);
wolfSSL 7:481bce714567 407 if (!r) r = SrpHashUpdate(&hash, password, size);
wolfSSL 7:481bce714567 408 if (!r) r = SrpHashFinal(&hash, digest);
wolfSSL 7:481bce714567 409
wolfSSL 7:481bce714567 410 /* digest = H(salt | H(username | ':' | password)) */
wolfSSL 7:481bce714567 411 if (!r) r = SrpHashInit(&hash, srp->type);
wolfSSL 7:481bce714567 412 if (!r) r = SrpHashUpdate(&hash, srp->salt, srp->saltSz);
wolfSSL 7:481bce714567 413 if (!r) r = SrpHashUpdate(&hash, digest, digestSz);
wolfSSL 7:481bce714567 414 if (!r) r = SrpHashFinal(&hash, digest);
wolfSSL 7:481bce714567 415
wolfSSL 7:481bce714567 416 /* Set x (private key) */
wolfSSL 7:481bce714567 417 if (!r) r = mp_read_unsigned_bin(&srp->auth, digest, digestSz);
wolfSSL 7:481bce714567 418
wolfSSL 7:481bce714567 419 ForceZero(digest, SRP_MAX_DIGEST_SIZE);
wolfSSL 7:481bce714567 420
wolfSSL 7:481bce714567 421 return r;
wolfSSL 7:481bce714567 422 }
wolfSSL 7:481bce714567 423
wolfSSL 7:481bce714567 424 int wc_SrpGetVerifier(Srp* srp, byte* verifier, word32* size)
wolfSSL 7:481bce714567 425 {
wolfSSL 7:481bce714567 426 mp_int v;
wolfSSL 7:481bce714567 427 int r;
wolfSSL 7:481bce714567 428
wolfSSL 7:481bce714567 429 if (!srp || !verifier || !size || srp->side != SRP_CLIENT_SIDE)
wolfSSL 7:481bce714567 430 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 431
wolfSSL 7:481bce714567 432 if (mp_iszero(&srp->auth) == MP_YES)
wolfSSL 7:481bce714567 433 return SRP_CALL_ORDER_E;
wolfSSL 7:481bce714567 434
wolfSSL 7:481bce714567 435 r = mp_init(&v);
wolfSSL 7:481bce714567 436 if (r != MP_OKAY)
wolfSSL 7:481bce714567 437 return MP_INIT_E;
wolfSSL 7:481bce714567 438
wolfSSL 7:481bce714567 439 /* v = g ^ x % N */
wolfSSL 7:481bce714567 440 if (!r) r = mp_exptmod(&srp->g, &srp->auth, &srp->N, &v);
wolfSSL 7:481bce714567 441 if (!r) r = *size < (word32)mp_unsigned_bin_size(&v) ? BUFFER_E : MP_OKAY;
wolfSSL 7:481bce714567 442 if (!r) r = mp_to_unsigned_bin(&v, verifier);
wolfSSL 7:481bce714567 443 if (!r) *size = mp_unsigned_bin_size(&v);
wolfSSL 7:481bce714567 444
wolfSSL 7:481bce714567 445 mp_clear(&v);
wolfSSL 7:481bce714567 446
wolfSSL 7:481bce714567 447 return r;
wolfSSL 7:481bce714567 448 }
wolfSSL 7:481bce714567 449
wolfSSL 7:481bce714567 450 int wc_SrpSetVerifier(Srp* srp, const byte* verifier, word32 size)
wolfSSL 7:481bce714567 451 {
wolfSSL 7:481bce714567 452 if (!srp || !verifier || srp->side != SRP_SERVER_SIDE)
wolfSSL 7:481bce714567 453 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 454
wolfSSL 7:481bce714567 455 return mp_read_unsigned_bin(&srp->auth, verifier, size);
wolfSSL 7:481bce714567 456 }
wolfSSL 7:481bce714567 457
wolfSSL 7:481bce714567 458 int wc_SrpSetPrivate(Srp* srp, const byte* priv, word32 size)
wolfSSL 7:481bce714567 459 {
wolfSSL 7:481bce714567 460 mp_int p;
wolfSSL 7:481bce714567 461 int r;
wolfSSL 7:481bce714567 462
wolfSSL 7:481bce714567 463 if (!srp || !priv || !size)
wolfSSL 7:481bce714567 464 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 465
wolfSSL 7:481bce714567 466 if (mp_iszero(&srp->auth) == MP_YES)
wolfSSL 7:481bce714567 467 return SRP_CALL_ORDER_E;
wolfSSL 7:481bce714567 468
wolfSSL 7:481bce714567 469 r = mp_init(&p);
wolfSSL 7:481bce714567 470 if (r != MP_OKAY)
wolfSSL 7:481bce714567 471 return MP_INIT_E;
wolfSSL 7:481bce714567 472 if (!r) r = mp_read_unsigned_bin(&p, priv, size);
wolfSSL 7:481bce714567 473 if (!r) r = mp_mod(&p, &srp->N, &srp->priv);
wolfSSL 7:481bce714567 474 if (!r) r = mp_iszero(&srp->priv) == MP_YES ? SRP_BAD_KEY_E : 0;
wolfSSL 7:481bce714567 475
wolfSSL 7:481bce714567 476 mp_clear(&p);
wolfSSL 7:481bce714567 477
wolfSSL 7:481bce714567 478 return r;
wolfSSL 7:481bce714567 479 }
wolfSSL 7:481bce714567 480
wolfSSL 7:481bce714567 481 /** Generates random data using wolfcrypt RNG. */
wolfSSL 7:481bce714567 482 static int wc_SrpGenPrivate(Srp* srp, byte* priv, word32 size)
wolfSSL 7:481bce714567 483 {
wolfSSL 7:481bce714567 484 WC_RNG rng;
wolfSSL 7:481bce714567 485 int r = wc_InitRng(&rng);
wolfSSL 7:481bce714567 486
wolfSSL 7:481bce714567 487 if (!r) r = wc_RNG_GenerateBlock(&rng, priv, size);
wolfSSL 7:481bce714567 488 if (!r) r = wc_SrpSetPrivate(srp, priv, size);
wolfSSL 7:481bce714567 489 if (!r) wc_FreeRng(&rng);
wolfSSL 7:481bce714567 490
wolfSSL 7:481bce714567 491 return r;
wolfSSL 7:481bce714567 492 }
wolfSSL 7:481bce714567 493
wolfSSL 7:481bce714567 494 int wc_SrpGetPublic(Srp* srp, byte* pub, word32* size)
wolfSSL 7:481bce714567 495 {
wolfSSL 7:481bce714567 496 mp_int pubkey;
wolfSSL 7:481bce714567 497 word32 modulusSz;
wolfSSL 7:481bce714567 498 int r;
wolfSSL 7:481bce714567 499
wolfSSL 7:481bce714567 500 if (!srp || !pub || !size)
wolfSSL 7:481bce714567 501 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 502
wolfSSL 7:481bce714567 503 if (mp_iszero(&srp->auth) == MP_YES)
wolfSSL 7:481bce714567 504 return SRP_CALL_ORDER_E;
wolfSSL 7:481bce714567 505
wolfSSL 7:481bce714567 506 modulusSz = mp_unsigned_bin_size(&srp->N);
wolfSSL 7:481bce714567 507 if (*size < modulusSz)
wolfSSL 7:481bce714567 508 return BUFFER_E;
wolfSSL 7:481bce714567 509
wolfSSL 7:481bce714567 510 r = mp_init(&pubkey);
wolfSSL 7:481bce714567 511 if (r != MP_OKAY)
wolfSSL 7:481bce714567 512 return MP_INIT_E;
wolfSSL 7:481bce714567 513
wolfSSL 7:481bce714567 514 /* priv = random() */
wolfSSL 7:481bce714567 515 if (mp_iszero(&srp->priv) == MP_YES)
wolfSSL 7:481bce714567 516 r = wc_SrpGenPrivate(srp, pub, SRP_PRIVATE_KEY_MIN_BITS / 8);
wolfSSL 7:481bce714567 517
wolfSSL 7:481bce714567 518 /* client side: A = g ^ a % N */
wolfSSL 7:481bce714567 519 if (srp->side == SRP_CLIENT_SIDE) {
wolfSSL 7:481bce714567 520 if (!r) r = mp_exptmod(&srp->g, &srp->priv, &srp->N, &pubkey);
wolfSSL 7:481bce714567 521
wolfSSL 7:481bce714567 522 /* server side: B = (k * v + (g ^ b % N)) % N */
wolfSSL 7:481bce714567 523 } else {
wolfSSL 7:481bce714567 524 mp_int i, j;
wolfSSL 7:481bce714567 525
wolfSSL 7:481bce714567 526 if (mp_init_multi(&i, &j, 0, 0, 0, 0) == MP_OKAY) {
wolfSSL 7:481bce714567 527 if (!r) r = mp_read_unsigned_bin(&i, srp->k,SrpHashSize(srp->type));
wolfSSL 7:481bce714567 528 if (!r) r = mp_iszero(&i) == MP_YES ? SRP_BAD_KEY_E : 0;
wolfSSL 7:481bce714567 529 if (!r) r = mp_exptmod(&srp->g, &srp->priv, &srp->N, &pubkey);
wolfSSL 7:481bce714567 530 if (!r) r = mp_mulmod(&i, &srp->auth, &srp->N, &j);
wolfSSL 7:481bce714567 531 if (!r) r = mp_add(&j, &pubkey, &i);
wolfSSL 7:481bce714567 532 if (!r) r = mp_mod(&i, &srp->N, &pubkey);
wolfSSL 7:481bce714567 533
wolfSSL 7:481bce714567 534 mp_clear(&i); mp_clear(&j);
wolfSSL 7:481bce714567 535 }
wolfSSL 7:481bce714567 536 }
wolfSSL 7:481bce714567 537
wolfSSL 7:481bce714567 538 /* extract public key to buffer */
wolfSSL 7:481bce714567 539 XMEMSET(pub, 0, modulusSz);
wolfSSL 7:481bce714567 540 if (!r) r = mp_to_unsigned_bin(&pubkey, pub);
wolfSSL 7:481bce714567 541 if (!r) *size = mp_unsigned_bin_size(&pubkey);
wolfSSL 7:481bce714567 542 mp_clear(&pubkey);
wolfSSL 7:481bce714567 543
wolfSSL 7:481bce714567 544 return r;
wolfSSL 7:481bce714567 545 }
wolfSSL 7:481bce714567 546
wolfSSL 7:481bce714567 547 static int wc_SrpSetKey(Srp* srp, byte* secret, word32 size)
wolfSSL 7:481bce714567 548 {
wolfSSL 7:481bce714567 549 SrpHash hash;
wolfSSL 7:481bce714567 550 byte digest[SRP_MAX_DIGEST_SIZE];
wolfSSL 7:481bce714567 551 word32 i, j, digestSz = SrpHashSize(srp->type);
wolfSSL 7:481bce714567 552 byte counter[4];
wolfSSL 7:481bce714567 553 int r = BAD_FUNC_ARG;
wolfSSL 7:481bce714567 554
wolfSSL 7:481bce714567 555 srp->key = (byte*)XMALLOC(2 * digestSz, srp->heap, DYNAMIC_TYPE_SRP);
wolfSSL 7:481bce714567 556 if (srp->key == NULL)
wolfSSL 7:481bce714567 557 return MEMORY_E;
wolfSSL 7:481bce714567 558
wolfSSL 7:481bce714567 559 srp->keySz = 2 * digestSz;
wolfSSL 7:481bce714567 560
wolfSSL 7:481bce714567 561 for (i = j = 0; j < srp->keySz; i++) {
wolfSSL 7:481bce714567 562 counter[0] = (i >> 24) & 0xFF;
wolfSSL 7:481bce714567 563 counter[1] = (i >> 16) & 0xFF;
wolfSSL 7:481bce714567 564 counter[2] = (i >> 8) & 0xFF;
wolfSSL 7:481bce714567 565 counter[3] = i & 0xFF;
wolfSSL 7:481bce714567 566
wolfSSL 7:481bce714567 567 r = SrpHashInit(&hash, srp->type);
wolfSSL 7:481bce714567 568 if (!r) r = SrpHashUpdate(&hash, secret, size);
wolfSSL 7:481bce714567 569 if (!r) r = SrpHashUpdate(&hash, counter, 4);
wolfSSL 7:481bce714567 570
wolfSSL 7:481bce714567 571 if(j + digestSz > srp->keySz) {
wolfSSL 7:481bce714567 572 if (!r) r = SrpHashFinal(&hash, digest);
wolfSSL 7:481bce714567 573 XMEMCPY(srp->key + j, digest, srp->keySz - j);
wolfSSL 7:481bce714567 574 j = srp->keySz;
wolfSSL 7:481bce714567 575 }
wolfSSL 7:481bce714567 576 else {
wolfSSL 7:481bce714567 577 if (!r) r = SrpHashFinal(&hash, srp->key + j);
wolfSSL 7:481bce714567 578 j += digestSz;
wolfSSL 7:481bce714567 579 }
wolfSSL 7:481bce714567 580 }
wolfSSL 7:481bce714567 581
wolfSSL 7:481bce714567 582 ForceZero(digest, sizeof(digest));
wolfSSL 7:481bce714567 583 ForceZero(&hash, sizeof(SrpHash));
wolfSSL 7:481bce714567 584
wolfSSL 7:481bce714567 585 return r;
wolfSSL 7:481bce714567 586 }
wolfSSL 7:481bce714567 587
wolfSSL 7:481bce714567 588 int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz,
wolfSSL 7:481bce714567 589 byte* serverPubKey, word32 serverPubKeySz)
wolfSSL 7:481bce714567 590 {
wolfSSL 7:481bce714567 591 SrpHash hash;
wolfSSL 7:481bce714567 592 byte *secret;
wolfSSL 7:481bce714567 593 byte digest[SRP_MAX_DIGEST_SIZE];
wolfSSL 7:481bce714567 594 word32 i, secretSz, digestSz;
wolfSSL 7:481bce714567 595 mp_int u, s, temp1, temp2;
wolfSSL 7:481bce714567 596 byte pad = 0;
wolfSSL 7:481bce714567 597 int r;
wolfSSL 7:481bce714567 598
wolfSSL 7:481bce714567 599 /* validating params */
wolfSSL 7:481bce714567 600
wolfSSL 7:481bce714567 601 if (!srp || !clientPubKey || clientPubKeySz == 0
wolfSSL 7:481bce714567 602 || !serverPubKey || serverPubKeySz == 0)
wolfSSL 7:481bce714567 603 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 604
wolfSSL 7:481bce714567 605 if (mp_iszero(&srp->priv) == MP_YES)
wolfSSL 7:481bce714567 606 return SRP_CALL_ORDER_E;
wolfSSL 7:481bce714567 607
wolfSSL 7:481bce714567 608 /* initializing variables */
wolfSSL 7:481bce714567 609
wolfSSL 7:481bce714567 610 if ((r = SrpHashInit(&hash, srp->type)) != 0)
wolfSSL 7:481bce714567 611 return r;
wolfSSL 7:481bce714567 612
wolfSSL 7:481bce714567 613 digestSz = SrpHashSize(srp->type);
wolfSSL 7:481bce714567 614 secretSz = mp_unsigned_bin_size(&srp->N);
wolfSSL 7:481bce714567 615
wolfSSL 7:481bce714567 616 if ((secret = (byte*)XMALLOC(secretSz, srp->heap, DYNAMIC_TYPE_SRP)) ==NULL)
wolfSSL 7:481bce714567 617 return MEMORY_E;
wolfSSL 7:481bce714567 618
wolfSSL 7:481bce714567 619 if ((r = mp_init_multi(&u, &s, &temp1, &temp2, 0, 0)) != MP_OKAY) {
wolfSSL 7:481bce714567 620 XFREE(secret, srp->heap, DYNAMIC_TYPE_SRP);
wolfSSL 7:481bce714567 621 return r;
wolfSSL 7:481bce714567 622 }
wolfSSL 7:481bce714567 623
wolfSSL 7:481bce714567 624 /* building u (random scrambling parameter) */
wolfSSL 7:481bce714567 625
wolfSSL 7:481bce714567 626 /* H(A) */
wolfSSL 7:481bce714567 627 for (i = 0; !r && i < secretSz - clientPubKeySz; i++)
wolfSSL 7:481bce714567 628 r = SrpHashUpdate(&hash, &pad, 1);
wolfSSL 7:481bce714567 629 if (!r) r = SrpHashUpdate(&hash, clientPubKey, clientPubKeySz);
wolfSSL 7:481bce714567 630
wolfSSL 7:481bce714567 631 /* H(A | B) */
wolfSSL 7:481bce714567 632 for (i = 0; !r && i < secretSz - serverPubKeySz; i++)
wolfSSL 7:481bce714567 633 r = SrpHashUpdate(&hash, &pad, 1);
wolfSSL 7:481bce714567 634 if (!r) r = SrpHashUpdate(&hash, serverPubKey, serverPubKeySz);
wolfSSL 7:481bce714567 635
wolfSSL 7:481bce714567 636 /* set u */
wolfSSL 7:481bce714567 637 if (!r) r = SrpHashFinal(&hash, digest);
wolfSSL 7:481bce714567 638 if (!r) r = mp_read_unsigned_bin(&u, digest, SrpHashSize(srp->type));
wolfSSL 7:481bce714567 639
wolfSSL 7:481bce714567 640 /* building s (secret) */
wolfSSL 7:481bce714567 641
wolfSSL 7:481bce714567 642 if (!r && srp->side == SRP_CLIENT_SIDE) {
wolfSSL 7:481bce714567 643
wolfSSL 7:481bce714567 644 /* temp1 = B - k * v; rejects k == 0, B == 0 and B >= N. */
wolfSSL 7:481bce714567 645 r = mp_read_unsigned_bin(&temp1, srp->k, digestSz);
wolfSSL 7:481bce714567 646 if (!r) r = mp_iszero(&temp1) == MP_YES ? SRP_BAD_KEY_E : 0;
wolfSSL 7:481bce714567 647 if (!r) r = mp_exptmod(&srp->g, &srp->auth, &srp->N, &temp2);
wolfSSL 7:481bce714567 648 if (!r) r = mp_mulmod(&temp1, &temp2, &srp->N, &s);
wolfSSL 7:481bce714567 649 if (!r) r = mp_read_unsigned_bin(&temp2, serverPubKey, serverPubKeySz);
wolfSSL 7:481bce714567 650 if (!r) r = mp_iszero(&temp2) == MP_YES ? SRP_BAD_KEY_E : 0;
wolfSSL 7:481bce714567 651 if (!r) r = mp_cmp(&temp2, &srp->N) != MP_LT ? SRP_BAD_KEY_E : 0;
wolfSSL 7:481bce714567 652 if (!r) r = mp_sub(&temp2, &s, &temp1);
wolfSSL 7:481bce714567 653
wolfSSL 7:481bce714567 654 /* temp2 = a + u * x */
wolfSSL 7:481bce714567 655 if (!r) r = mp_mulmod(&u, &srp->auth, &srp->N, &s);
wolfSSL 7:481bce714567 656 if (!r) r = mp_add(&srp->priv, &s, &temp2);
wolfSSL 7:481bce714567 657
wolfSSL 7:481bce714567 658 /* secret = temp1 ^ temp2 % N */
wolfSSL 7:481bce714567 659 if (!r) r = mp_exptmod(&temp1, &temp2, &srp->N, &s);
wolfSSL 7:481bce714567 660
wolfSSL 7:481bce714567 661 } else if (!r && srp->side == SRP_SERVER_SIDE) {
wolfSSL 7:481bce714567 662 /* temp1 = v ^ u % N */
wolfSSL 7:481bce714567 663 r = mp_exptmod(&srp->auth, &u, &srp->N, &temp1);
wolfSSL 7:481bce714567 664
wolfSSL 7:481bce714567 665 /* temp2 = A * temp1 % N; rejects A == 0, A >= N */
wolfSSL 7:481bce714567 666 if (!r) r = mp_read_unsigned_bin(&s, clientPubKey, clientPubKeySz);
wolfSSL 7:481bce714567 667 if (!r) r = mp_iszero(&s) == MP_YES ? SRP_BAD_KEY_E : 0;
wolfSSL 7:481bce714567 668 if (!r) r = mp_cmp(&s, &srp->N) != MP_LT ? SRP_BAD_KEY_E : 0;
wolfSSL 7:481bce714567 669 if (!r) r = mp_mulmod(&s, &temp1, &srp->N, &temp2);
wolfSSL 7:481bce714567 670
wolfSSL 7:481bce714567 671 /* rejects A * v ^ u % N >= 1, A * v ^ u % N == -1 % N */
wolfSSL 7:481bce714567 672 if (!r) r = mp_read_unsigned_bin(&temp1, (const byte*)"\001", 1);
wolfSSL 7:481bce714567 673 if (!r) r = mp_cmp(&temp2, &temp1) != MP_GT ? SRP_BAD_KEY_E : 0;
wolfSSL 7:481bce714567 674 if (!r) r = mp_sub(&srp->N, &temp1, &s);
wolfSSL 7:481bce714567 675 if (!r) r = mp_cmp(&temp2, &s) == MP_EQ ? SRP_BAD_KEY_E : 0;
wolfSSL 7:481bce714567 676
wolfSSL 7:481bce714567 677 /* secret = temp2 * b % N */
wolfSSL 7:481bce714567 678 if (!r) r = mp_exptmod(&temp2, &srp->priv, &srp->N, &s);
wolfSSL 7:481bce714567 679 }
wolfSSL 7:481bce714567 680
wolfSSL 7:481bce714567 681 /* building session key from secret */
wolfSSL 7:481bce714567 682
wolfSSL 7:481bce714567 683 if (!r) r = mp_to_unsigned_bin(&s, secret);
wolfSSL 7:481bce714567 684 if (!r) r = srp->keyGenFunc_cb(srp, secret, mp_unsigned_bin_size(&s));
wolfSSL 7:481bce714567 685
wolfSSL 7:481bce714567 686 /* updating client proof = H( H(N) ^ H(g) | H(user) | salt | A | B | K) */
wolfSSL 7:481bce714567 687
wolfSSL 7:481bce714567 688 if (!r) r = SrpHashUpdate(&srp->client_proof, clientPubKey, clientPubKeySz);
wolfSSL 7:481bce714567 689 if (!r) r = SrpHashUpdate(&srp->client_proof, serverPubKey, serverPubKeySz);
wolfSSL 7:481bce714567 690 if (!r) r = SrpHashUpdate(&srp->client_proof, srp->key, srp->keySz);
wolfSSL 7:481bce714567 691
wolfSSL 7:481bce714567 692 /* updating server proof = H(A) */
wolfSSL 7:481bce714567 693
wolfSSL 7:481bce714567 694 if (!r) r = SrpHashUpdate(&srp->server_proof, clientPubKey, clientPubKeySz);
wolfSSL 7:481bce714567 695
wolfSSL 7:481bce714567 696 XFREE(secret, srp->heap, DYNAMIC_TYPE_SRP);
wolfSSL 7:481bce714567 697 mp_clear(&u); mp_clear(&s); mp_clear(&temp1); mp_clear(&temp2);
wolfSSL 7:481bce714567 698
wolfSSL 7:481bce714567 699 return r;
wolfSSL 7:481bce714567 700 }
wolfSSL 7:481bce714567 701
wolfSSL 7:481bce714567 702 int wc_SrpGetProof(Srp* srp, byte* proof, word32* size)
wolfSSL 7:481bce714567 703 {
wolfSSL 7:481bce714567 704 int r;
wolfSSL 7:481bce714567 705
wolfSSL 7:481bce714567 706 if (!srp || !proof || !size)
wolfSSL 7:481bce714567 707 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 708
wolfSSL 7:481bce714567 709 if (*size < SrpHashSize(srp->type))
wolfSSL 7:481bce714567 710 return BUFFER_E;
wolfSSL 7:481bce714567 711
wolfSSL 7:481bce714567 712 if ((r = SrpHashFinal(srp->side == SRP_CLIENT_SIDE
wolfSSL 7:481bce714567 713 ? &srp->client_proof
wolfSSL 7:481bce714567 714 : &srp->server_proof, proof)) != 0)
wolfSSL 7:481bce714567 715 return r;
wolfSSL 7:481bce714567 716
wolfSSL 7:481bce714567 717 *size = SrpHashSize(srp->type);
wolfSSL 7:481bce714567 718
wolfSSL 7:481bce714567 719 if (srp->side == SRP_CLIENT_SIDE) {
wolfSSL 7:481bce714567 720 /* server proof = H( A | client proof | K) */
wolfSSL 7:481bce714567 721 if (!r) r = SrpHashUpdate(&srp->server_proof, proof, *size);
wolfSSL 7:481bce714567 722 if (!r) r = SrpHashUpdate(&srp->server_proof, srp->key, srp->keySz);
wolfSSL 7:481bce714567 723 }
wolfSSL 7:481bce714567 724
wolfSSL 7:481bce714567 725 return r;
wolfSSL 7:481bce714567 726 }
wolfSSL 7:481bce714567 727
wolfSSL 7:481bce714567 728 int wc_SrpVerifyPeersProof(Srp* srp, byte* proof, word32 size)
wolfSSL 7:481bce714567 729 {
wolfSSL 7:481bce714567 730 byte digest[SRP_MAX_DIGEST_SIZE];
wolfSSL 7:481bce714567 731 int r;
wolfSSL 7:481bce714567 732
wolfSSL 7:481bce714567 733 if (!srp || !proof)
wolfSSL 7:481bce714567 734 return BAD_FUNC_ARG;
wolfSSL 7:481bce714567 735
wolfSSL 7:481bce714567 736 if (size != SrpHashSize(srp->type))
wolfSSL 7:481bce714567 737 return BUFFER_E;
wolfSSL 7:481bce714567 738
wolfSSL 7:481bce714567 739 r = SrpHashFinal(srp->side == SRP_CLIENT_SIDE ? &srp->server_proof
wolfSSL 7:481bce714567 740 : &srp->client_proof, digest);
wolfSSL 7:481bce714567 741
wolfSSL 7:481bce714567 742 if (srp->side == SRP_SERVER_SIDE) {
wolfSSL 7:481bce714567 743 /* server proof = H( A | client proof | K) */
wolfSSL 7:481bce714567 744 if (!r) r = SrpHashUpdate(&srp->server_proof, proof, size);
wolfSSL 7:481bce714567 745 if (!r) r = SrpHashUpdate(&srp->server_proof, srp->key, srp->keySz);
wolfSSL 7:481bce714567 746 }
wolfSSL 7:481bce714567 747
wolfSSL 7:481bce714567 748 if (!r && XMEMCMP(proof, digest, size) != 0)
wolfSSL 7:481bce714567 749 r = SRP_VERIFY_E;
wolfSSL 7:481bce714567 750
wolfSSL 7:481bce714567 751 return r;
wolfSSL 7:481bce714567 752 }
wolfSSL 7:481bce714567 753
wolfSSL 7:481bce714567 754 #endif /* WOLFCRYPT_HAVE_SRP */
wolfSSL 7:481bce714567 755