1 /* 2 * Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * Copyright (c) 2004, EdelKey Project. All Rights Reserved. 4 * 5 * Licensed under the OpenSSL license (the "License"). You may not use 6 * this file except in compliance with the License. You can obtain a copy 7 * in the file LICENSE in the source distribution or at 8 * https://www.openssl.org/source/license.html 9 * 10 * Originally written by Christophe Renou and Peter Sylvester, 11 * for the EdelKey project. 12 */ 13 14 #ifndef OPENSSL_NO_SRP 15 # include "internal/cryptlib.h" 16 # include "internal/evp_int.h" 17 # include <openssl/sha.h> 18 # include <openssl/srp.h> 19 # include <openssl/evp.h> 20 # include <openssl/buffer.h> 21 # include <openssl/rand.h> 22 # include <openssl/txt_db.h> 23 # include <openssl/err.h> 24 25 # define SRP_RANDOM_SALT_LEN 20 26 # define MAX_LEN 2500 27 28 /* 29 * Note that SRP uses its own variant of base 64 encoding. A different base64 30 * alphabet is used and no padding '=' characters are added. Instead we pad to 31 * the front with 0 bytes and subsequently strip off leading encoded padding. 32 * This variant is used for compatibility with other SRP implementations - 33 * notably libsrp, but also others. It is also required for backwards 34 * compatibility in order to load verifier files from other OpenSSL versions. 35 */ 36 37 /* 38 * Convert a base64 string into raw byte array representation. 39 * Returns the length of the decoded data, or -1 on error. 40 */ 41 static int t_fromb64(unsigned char *a, size_t alen, const char *src) 42 { 43 EVP_ENCODE_CTX *ctx; 44 int outl = 0, outl2 = 0; 45 size_t size, padsize; 46 const unsigned char *pad = (const unsigned char *)"00"; 47 48 while (*src == ' ' || *src == '\t' || *src == '\n') 49 ++src; 50 size = strlen(src); 51 padsize = 4 - (size & 3); 52 padsize &= 3; 53 54 /* Four bytes in src become three bytes output. */ 55 if (size > INT_MAX || ((size + padsize) / 4) * 3 > alen) 56 return -1; 57 58 ctx = EVP_ENCODE_CTX_new(); 59 if (ctx == NULL) 60 return -1; 61 62 /* 63 * This should never occur because 1 byte of data always requires 2 bytes of 64 * encoding, i.e. 65 * 0 bytes unencoded = 0 bytes encoded 66 * 1 byte unencoded = 2 bytes encoded 67 * 2 bytes unencoded = 3 bytes encoded 68 * 3 bytes unencoded = 4 bytes encoded 69 * 4 bytes unencoded = 6 bytes encoded 70 * etc 71 */ 72 if (padsize == 3) { 73 outl = -1; 74 goto err; 75 } 76 77 /* Valid padsize values are now 0, 1 or 2 */ 78 79 EVP_DecodeInit(ctx); 80 evp_encode_ctx_set_flags(ctx, EVP_ENCODE_CTX_USE_SRP_ALPHABET); 81 82 /* Add any encoded padding that is required */ 83 if (padsize != 0 84 && EVP_DecodeUpdate(ctx, a, &outl, pad, padsize) < 0) { 85 outl = -1; 86 goto err; 87 } 88 if (EVP_DecodeUpdate(ctx, a, &outl2, (const unsigned char *)src, size) < 0) { 89 outl = -1; 90 goto err; 91 } 92 outl += outl2; 93 EVP_DecodeFinal(ctx, a + outl, &outl2); 94 outl += outl2; 95 96 /* Strip off the leading padding */ 97 if (padsize != 0) { 98 if ((int)padsize >= outl) { 99 outl = -1; 100 goto err; 101 } 102 103 /* 104 * If we added 1 byte of padding prior to encoding then we have 2 bytes 105 * of "real" data which gets spread across 4 encoded bytes like this: 106 * (6 bits pad)(2 bits pad | 4 bits data)(6 bits data)(6 bits data) 107 * So 1 byte of pre-encoding padding results in 1 full byte of encoded 108 * padding. 109 * If we added 2 bytes of padding prior to encoding this gets encoded 110 * as: 111 * (6 bits pad)(6 bits pad)(4 bits pad | 2 bits data)(6 bits data) 112 * So 2 bytes of pre-encoding padding results in 2 full bytes of encoded 113 * padding, i.e. we have to strip the same number of bytes of padding 114 * from the encoded data as we added to the pre-encoded data. 115 */ 116 memmove(a, a + padsize, outl - padsize); 117 outl -= padsize; 118 } 119 120 err: 121 EVP_ENCODE_CTX_free(ctx); 122 123 return outl; 124 } 125 126 /* 127 * Convert a raw byte string into a null-terminated base64 ASCII string. 128 * Returns 1 on success or 0 on error. 129 */ 130 static int t_tob64(char *dst, const unsigned char *src, int size) 131 { 132 EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new(); 133 int outl = 0, outl2 = 0; 134 unsigned char pad[2] = {0, 0}; 135 size_t leadz = 0; 136 137 if (ctx == NULL) 138 return 0; 139 140 EVP_EncodeInit(ctx); 141 evp_encode_ctx_set_flags(ctx, EVP_ENCODE_CTX_NO_NEWLINES 142 | EVP_ENCODE_CTX_USE_SRP_ALPHABET); 143 144 /* 145 * We pad at the front with zero bytes until the length is a multiple of 3 146 * so that EVP_EncodeUpdate/EVP_EncodeFinal does not add any of its own "=" 147 * padding 148 */ 149 leadz = 3 - (size % 3); 150 if (leadz != 3 151 && !EVP_EncodeUpdate(ctx, (unsigned char *)dst, &outl, pad, 152 leadz)) { 153 EVP_ENCODE_CTX_free(ctx); 154 return 0; 155 } 156 157 if (!EVP_EncodeUpdate(ctx, (unsigned char *)dst + outl, &outl2, src, 158 size)) { 159 EVP_ENCODE_CTX_free(ctx); 160 return 0; 161 } 162 outl += outl2; 163 EVP_EncodeFinal(ctx, (unsigned char *)dst + outl, &outl2); 164 outl += outl2; 165 166 /* Strip the encoded padding at the front */ 167 if (leadz != 3) { 168 memmove(dst, dst + leadz, outl - leadz); 169 dst[outl - leadz] = '\0'; 170 } 171 172 EVP_ENCODE_CTX_free(ctx); 173 return 1; 174 } 175 176 void SRP_user_pwd_free(SRP_user_pwd *user_pwd) 177 { 178 if (user_pwd == NULL) 179 return; 180 BN_free(user_pwd->s); 181 BN_clear_free(user_pwd->v); 182 OPENSSL_free(user_pwd->id); 183 OPENSSL_free(user_pwd->info); 184 OPENSSL_free(user_pwd); 185 } 186 187 static SRP_user_pwd *SRP_user_pwd_new(void) 188 { 189 SRP_user_pwd *ret; 190 191 if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) { 192 /* SRPerr(SRP_F_SRP_USER_PWD_NEW, ERR_R_MALLOC_FAILURE); */ /*ckerr_ignore*/ 193 return NULL; 194 } 195 ret->N = NULL; 196 ret->g = NULL; 197 ret->s = NULL; 198 ret->v = NULL; 199 ret->id = NULL; 200 ret->info = NULL; 201 return ret; 202 } 203 204 static void SRP_user_pwd_set_gN(SRP_user_pwd *vinfo, const BIGNUM *g, 205 const BIGNUM *N) 206 { 207 vinfo->N = N; 208 vinfo->g = g; 209 } 210 211 static int SRP_user_pwd_set_ids(SRP_user_pwd *vinfo, const char *id, 212 const char *info) 213 { 214 if (id != NULL && NULL == (vinfo->id = OPENSSL_strdup(id))) 215 return 0; 216 return (info == NULL || NULL != (vinfo->info = OPENSSL_strdup(info))); 217 } 218 219 static int SRP_user_pwd_set_sv(SRP_user_pwd *vinfo, const char *s, 220 const char *v) 221 { 222 unsigned char tmp[MAX_LEN]; 223 int len; 224 225 vinfo->v = NULL; 226 vinfo->s = NULL; 227 228 len = t_fromb64(tmp, sizeof(tmp), v); 229 if (len < 0) 230 return 0; 231 if (NULL == (vinfo->v = BN_bin2bn(tmp, len, NULL))) 232 return 0; 233 len = t_fromb64(tmp, sizeof(tmp), s); 234 if (len < 0) 235 goto err; 236 vinfo->s = BN_bin2bn(tmp, len, NULL); 237 if (vinfo->s == NULL) 238 goto err; 239 return 1; 240 err: 241 BN_free(vinfo->v); 242 vinfo->v = NULL; 243 return 0; 244 } 245 246 static int SRP_user_pwd_set_sv_BN(SRP_user_pwd *vinfo, BIGNUM *s, BIGNUM *v) 247 { 248 vinfo->v = v; 249 vinfo->s = s; 250 return (vinfo->s != NULL && vinfo->v != NULL); 251 } 252 253 static SRP_user_pwd *srp_user_pwd_dup(SRP_user_pwd *src) 254 { 255 SRP_user_pwd *ret; 256 257 if (src == NULL) 258 return NULL; 259 if ((ret = SRP_user_pwd_new()) == NULL) 260 return NULL; 261 262 SRP_user_pwd_set_gN(ret, src->g, src->N); 263 if (!SRP_user_pwd_set_ids(ret, src->id, src->info) 264 || !SRP_user_pwd_set_sv_BN(ret, BN_dup(src->s), BN_dup(src->v))) { 265 SRP_user_pwd_free(ret); 266 return NULL; 267 } 268 return ret; 269 } 270 271 SRP_VBASE *SRP_VBASE_new(char *seed_key) 272 { 273 SRP_VBASE *vb = OPENSSL_malloc(sizeof(*vb)); 274 275 if (vb == NULL) 276 return NULL; 277 if ((vb->users_pwd = sk_SRP_user_pwd_new_null()) == NULL 278 || (vb->gN_cache = sk_SRP_gN_cache_new_null()) == NULL) { 279 OPENSSL_free(vb); 280 return NULL; 281 } 282 vb->default_g = NULL; 283 vb->default_N = NULL; 284 vb->seed_key = NULL; 285 if ((seed_key != NULL) && (vb->seed_key = OPENSSL_strdup(seed_key)) == NULL) { 286 sk_SRP_user_pwd_free(vb->users_pwd); 287 sk_SRP_gN_cache_free(vb->gN_cache); 288 OPENSSL_free(vb); 289 return NULL; 290 } 291 return vb; 292 } 293 294 void SRP_VBASE_free(SRP_VBASE *vb) 295 { 296 if (!vb) 297 return; 298 sk_SRP_user_pwd_pop_free(vb->users_pwd, SRP_user_pwd_free); 299 sk_SRP_gN_cache_free(vb->gN_cache); 300 OPENSSL_free(vb->seed_key); 301 OPENSSL_free(vb); 302 } 303 304 static SRP_gN_cache *SRP_gN_new_init(const char *ch) 305 { 306 unsigned char tmp[MAX_LEN]; 307 int len; 308 SRP_gN_cache *newgN = OPENSSL_malloc(sizeof(*newgN)); 309 310 if (newgN == NULL) 311 return NULL; 312 313 len = t_fromb64(tmp, sizeof(tmp), ch); 314 if (len < 0) 315 goto err; 316 317 if ((newgN->b64_bn = OPENSSL_strdup(ch)) == NULL) 318 goto err; 319 320 if ((newgN->bn = BN_bin2bn(tmp, len, NULL))) 321 return newgN; 322 323 OPENSSL_free(newgN->b64_bn); 324 err: 325 OPENSSL_free(newgN); 326 return NULL; 327 } 328 329 static void SRP_gN_free(SRP_gN_cache *gN_cache) 330 { 331 if (gN_cache == NULL) 332 return; 333 OPENSSL_free(gN_cache->b64_bn); 334 BN_free(gN_cache->bn); 335 OPENSSL_free(gN_cache); 336 } 337 338 static SRP_gN *SRP_get_gN_by_id(const char *id, STACK_OF(SRP_gN) *gN_tab) 339 { 340 int i; 341 342 SRP_gN *gN; 343 if (gN_tab != NULL) 344 for (i = 0; i < sk_SRP_gN_num(gN_tab); i++) { 345 gN = sk_SRP_gN_value(gN_tab, i); 346 if (gN && (id == NULL || strcmp(gN->id, id) == 0)) 347 return gN; 348 } 349 350 return SRP_get_default_gN(id); 351 } 352 353 static BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch) 354 { 355 int i; 356 if (gN_cache == NULL) 357 return NULL; 358 359 /* search if we have already one... */ 360 for (i = 0; i < sk_SRP_gN_cache_num(gN_cache); i++) { 361 SRP_gN_cache *cache = sk_SRP_gN_cache_value(gN_cache, i); 362 if (strcmp(cache->b64_bn, ch) == 0) 363 return cache->bn; 364 } 365 { /* it is the first time that we find it */ 366 SRP_gN_cache *newgN = SRP_gN_new_init(ch); 367 if (newgN) { 368 if (sk_SRP_gN_cache_insert(gN_cache, newgN, 0) > 0) 369 return newgN->bn; 370 SRP_gN_free(newgN); 371 } 372 } 373 return NULL; 374 } 375 376 /* 377 * this function parses verifier file. Format is: 378 * string(index):base64(N):base64(g):0 379 * string(username):base64(v):base64(salt):int(index) 380 */ 381 382 int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file) 383 { 384 int error_code; 385 STACK_OF(SRP_gN) *SRP_gN_tab = sk_SRP_gN_new_null(); 386 char *last_index = NULL; 387 int i; 388 char **pp; 389 390 SRP_gN *gN = NULL; 391 SRP_user_pwd *user_pwd = NULL; 392 393 TXT_DB *tmpdb = NULL; 394 BIO *in = BIO_new(BIO_s_file()); 395 396 error_code = SRP_ERR_OPEN_FILE; 397 398 if (in == NULL || BIO_read_filename(in, verifier_file) <= 0) 399 goto err; 400 401 error_code = SRP_ERR_VBASE_INCOMPLETE_FILE; 402 403 if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL) 404 goto err; 405 406 error_code = SRP_ERR_MEMORY; 407 408 if (vb->seed_key) { 409 last_index = SRP_get_default_gN(NULL)->id; 410 } 411 for (i = 0; i < sk_OPENSSL_PSTRING_num(tmpdb->data); i++) { 412 pp = sk_OPENSSL_PSTRING_value(tmpdb->data, i); 413 if (pp[DB_srptype][0] == DB_SRP_INDEX) { 414 /* 415 * we add this couple in the internal Stack 416 */ 417 418 if ((gN = OPENSSL_malloc(sizeof(*gN))) == NULL) 419 goto err; 420 421 if ((gN->id = OPENSSL_strdup(pp[DB_srpid])) == NULL 422 || (gN->N = SRP_gN_place_bn(vb->gN_cache, pp[DB_srpverifier])) 423 == NULL 424 || (gN->g = SRP_gN_place_bn(vb->gN_cache, pp[DB_srpsalt])) 425 == NULL 426 || sk_SRP_gN_insert(SRP_gN_tab, gN, 0) == 0) 427 goto err; 428 429 gN = NULL; 430 431 if (vb->seed_key != NULL) { 432 last_index = pp[DB_srpid]; 433 } 434 } else if (pp[DB_srptype][0] == DB_SRP_VALID) { 435 /* it is a user .... */ 436 const SRP_gN *lgN; 437 438 if ((lgN = SRP_get_gN_by_id(pp[DB_srpgN], SRP_gN_tab)) != NULL) { 439 error_code = SRP_ERR_MEMORY; 440 if ((user_pwd = SRP_user_pwd_new()) == NULL) 441 goto err; 442 443 SRP_user_pwd_set_gN(user_pwd, lgN->g, lgN->N); 444 if (!SRP_user_pwd_set_ids 445 (user_pwd, pp[DB_srpid], pp[DB_srpinfo])) 446 goto err; 447 448 error_code = SRP_ERR_VBASE_BN_LIB; 449 if (!SRP_user_pwd_set_sv 450 (user_pwd, pp[DB_srpsalt], pp[DB_srpverifier])) 451 goto err; 452 453 if (sk_SRP_user_pwd_insert(vb->users_pwd, user_pwd, 0) == 0) 454 goto err; 455 user_pwd = NULL; /* abandon responsibility */ 456 } 457 } 458 } 459 460 if (last_index != NULL) { 461 /* this means that we want to simulate a default user */ 462 463 if (((gN = SRP_get_gN_by_id(last_index, SRP_gN_tab)) == NULL)) { 464 error_code = SRP_ERR_VBASE_BN_LIB; 465 goto err; 466 } 467 vb->default_g = gN->g; 468 vb->default_N = gN->N; 469 gN = NULL; 470 } 471 error_code = SRP_NO_ERROR; 472 473 err: 474 /* 475 * there may be still some leaks to fix, if this fails, the application 476 * terminates most likely 477 */ 478 479 if (gN != NULL) { 480 OPENSSL_free(gN->id); 481 OPENSSL_free(gN); 482 } 483 484 SRP_user_pwd_free(user_pwd); 485 486 TXT_DB_free(tmpdb); 487 BIO_free_all(in); 488 489 sk_SRP_gN_free(SRP_gN_tab); 490 491 return error_code; 492 493 } 494 495 static SRP_user_pwd *find_user(SRP_VBASE *vb, char *username) 496 { 497 int i; 498 SRP_user_pwd *user; 499 500 if (vb == NULL) 501 return NULL; 502 503 for (i = 0; i < sk_SRP_user_pwd_num(vb->users_pwd); i++) { 504 user = sk_SRP_user_pwd_value(vb->users_pwd, i); 505 if (strcmp(user->id, username) == 0) 506 return user; 507 } 508 509 return NULL; 510 } 511 512 # if OPENSSL_API_COMPAT < 0x10100000L 513 /* 514 * DEPRECATED: use SRP_VBASE_get1_by_user instead. 515 * This method ignores the configured seed and fails for an unknown user. 516 * Ownership of the returned pointer is not released to the caller. 517 * In other words, caller must not free the result. 518 */ 519 SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username) 520 { 521 return find_user(vb, username); 522 } 523 # endif 524 525 /* 526 * Ownership of the returned pointer is released to the caller. 527 * In other words, caller must free the result once done. 528 */ 529 SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username) 530 { 531 SRP_user_pwd *user; 532 unsigned char digv[SHA_DIGEST_LENGTH]; 533 unsigned char digs[SHA_DIGEST_LENGTH]; 534 EVP_MD_CTX *ctxt = NULL; 535 536 if (vb == NULL) 537 return NULL; 538 539 if ((user = find_user(vb, username)) != NULL) 540 return srp_user_pwd_dup(user); 541 542 if ((vb->seed_key == NULL) || 543 (vb->default_g == NULL) || (vb->default_N == NULL)) 544 return NULL; 545 546 /* if the user is unknown we set parameters as well if we have a seed_key */ 547 548 if ((user = SRP_user_pwd_new()) == NULL) 549 return NULL; 550 551 SRP_user_pwd_set_gN(user, vb->default_g, vb->default_N); 552 553 if (!SRP_user_pwd_set_ids(user, username, NULL)) 554 goto err; 555 556 if (RAND_priv_bytes(digv, SHA_DIGEST_LENGTH) <= 0) 557 goto err; 558 ctxt = EVP_MD_CTX_new(); 559 if (ctxt == NULL 560 || !EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL) 561 || !EVP_DigestUpdate(ctxt, vb->seed_key, strlen(vb->seed_key)) 562 || !EVP_DigestUpdate(ctxt, username, strlen(username)) 563 || !EVP_DigestFinal_ex(ctxt, digs, NULL)) 564 goto err; 565 EVP_MD_CTX_free(ctxt); 566 ctxt = NULL; 567 if (SRP_user_pwd_set_sv_BN(user, 568 BN_bin2bn(digs, SHA_DIGEST_LENGTH, NULL), 569 BN_bin2bn(digv, SHA_DIGEST_LENGTH, NULL))) 570 return user; 571 572 err: 573 EVP_MD_CTX_free(ctxt); 574 SRP_user_pwd_free(user); 575 return NULL; 576 } 577 578 /* 579 * create a verifier (*salt,*verifier,g and N are in base64) 580 */ 581 char *SRP_create_verifier(const char *user, const char *pass, char **salt, 582 char **verifier, const char *N, const char *g) 583 { 584 int len; 585 char *result = NULL, *vf = NULL; 586 const BIGNUM *N_bn = NULL, *g_bn = NULL; 587 BIGNUM *N_bn_alloc = NULL, *g_bn_alloc = NULL, *s = NULL, *v = NULL; 588 unsigned char tmp[MAX_LEN]; 589 unsigned char tmp2[MAX_LEN]; 590 char *defgNid = NULL; 591 int vfsize = 0; 592 593 if ((user == NULL) || 594 (pass == NULL) || (salt == NULL) || (verifier == NULL)) 595 goto err; 596 597 if (N) { 598 if ((len = t_fromb64(tmp, sizeof(tmp), N)) <= 0) 599 goto err; 600 N_bn_alloc = BN_bin2bn(tmp, len, NULL); 601 N_bn = N_bn_alloc; 602 if ((len = t_fromb64(tmp, sizeof(tmp) ,g)) <= 0) 603 goto err; 604 g_bn_alloc = BN_bin2bn(tmp, len, NULL); 605 g_bn = g_bn_alloc; 606 defgNid = "*"; 607 } else { 608 SRP_gN *gN = SRP_get_gN_by_id(g, NULL); 609 if (gN == NULL) 610 goto err; 611 N_bn = gN->N; 612 g_bn = gN->g; 613 defgNid = gN->id; 614 } 615 616 if (*salt == NULL) { 617 if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0) 618 goto err; 619 620 s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL); 621 } else { 622 if ((len = t_fromb64(tmp2, sizeof(tmp2), *salt)) <= 0) 623 goto err; 624 s = BN_bin2bn(tmp2, len, NULL); 625 } 626 627 if (!SRP_create_verifier_BN(user, pass, &s, &v, N_bn, g_bn)) 628 goto err; 629 630 BN_bn2bin(v, tmp); 631 vfsize = BN_num_bytes(v) * 2; 632 if (((vf = OPENSSL_malloc(vfsize)) == NULL)) 633 goto err; 634 t_tob64(vf, tmp, BN_num_bytes(v)); 635 636 if (*salt == NULL) { 637 char *tmp_salt; 638 639 if ((tmp_salt = OPENSSL_malloc(SRP_RANDOM_SALT_LEN * 2)) == NULL) { 640 goto err; 641 } 642 t_tob64(tmp_salt, tmp2, SRP_RANDOM_SALT_LEN); 643 *salt = tmp_salt; 644 } 645 646 *verifier = vf; 647 vf = NULL; 648 result = defgNid; 649 650 err: 651 BN_free(N_bn_alloc); 652 BN_free(g_bn_alloc); 653 OPENSSL_clear_free(vf, vfsize); 654 BN_clear_free(s); 655 BN_clear_free(v); 656 return result; 657 } 658 659 /* 660 * create a verifier (*salt,*verifier,g and N are BIGNUMs). If *salt != NULL 661 * then the provided salt will be used. On successful exit *verifier will point 662 * to a newly allocated BIGNUM containing the verifier and (if a salt was not 663 * provided) *salt will be populated with a newly allocated BIGNUM containing a 664 * random salt. 665 * The caller is responsible for freeing the allocated *salt and *verifier 666 * BIGNUMS. 667 */ 668 int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, 669 BIGNUM **verifier, const BIGNUM *N, 670 const BIGNUM *g) 671 { 672 int result = 0; 673 BIGNUM *x = NULL; 674 BN_CTX *bn_ctx = BN_CTX_new(); 675 unsigned char tmp2[MAX_LEN]; 676 BIGNUM *salttmp = NULL; 677 678 if ((user == NULL) || 679 (pass == NULL) || 680 (salt == NULL) || 681 (verifier == NULL) || (N == NULL) || (g == NULL) || (bn_ctx == NULL)) 682 goto err; 683 684 if (*salt == NULL) { 685 if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0) 686 goto err; 687 688 salttmp = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL); 689 } else { 690 salttmp = *salt; 691 } 692 693 x = SRP_Calc_x(salttmp, user, pass); 694 695 *verifier = BN_new(); 696 if (*verifier == NULL) 697 goto err; 698 699 if (!BN_mod_exp(*verifier, g, x, N, bn_ctx)) { 700 BN_clear_free(*verifier); 701 goto err; 702 } 703 704 result = 1; 705 *salt = salttmp; 706 707 err: 708 if (salt != NULL && *salt != salttmp) 709 BN_clear_free(salttmp); 710 BN_clear_free(x); 711 BN_CTX_free(bn_ctx); 712 return result; 713 } 714 715 #endif 716