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

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

Committer:
wolfSSL
Date:
Tue Aug 22 10:48:22 2017 +0000
Revision:
13:f67a6c6013ca
Parent:
11:cee25a834751
wolfSSL3.12.0 with TLS1.3

Who changed what in which revision?

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