1 /* 2 * Copyright 2004-2021 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 <openssl/sha.h> 17 # include <openssl/srp.h> 18 # include <openssl/evp.h> 19 # include "crypto/bn_srp.h" 20 21 /* calculate = SHA1(PAD(x) || PAD(y)) */ 22 23 static BIGNUM *srp_Calc_xy(const BIGNUM *x, const BIGNUM *y, const BIGNUM *N) 24 { 25 unsigned char digest[SHA_DIGEST_LENGTH]; 26 unsigned char *tmp = NULL; 27 int numN = BN_num_bytes(N); 28 BIGNUM *res = NULL; 29 30 if (x != N && BN_ucmp(x, N) >= 0) 31 return NULL; 32 if (y != N && BN_ucmp(y, N) >= 0) 33 return NULL; 34 if ((tmp = OPENSSL_malloc(numN * 2)) == NULL) 35 goto err; 36 if (BN_bn2binpad(x, tmp, numN) < 0 37 || BN_bn2binpad(y, tmp + numN, numN) < 0 38 || !EVP_Digest(tmp, numN * 2, digest, NULL, EVP_sha1(), NULL)) 39 goto err; 40 res = BN_bin2bn(digest, sizeof(digest), NULL); 41 err: 42 OPENSSL_free(tmp); 43 return res; 44 } 45 46 static BIGNUM *srp_Calc_k(const BIGNUM *N, const BIGNUM *g) 47 { 48 /* k = SHA1(N | PAD(g)) -- tls-srp draft 8 */ 49 return srp_Calc_xy(N, g, N); 50 } 51 52 BIGNUM *SRP_Calc_u(const BIGNUM *A, const BIGNUM *B, const BIGNUM *N) 53 { 54 /* k = SHA1(PAD(A) || PAD(B) ) -- tls-srp draft 8 */ 55 return srp_Calc_xy(A, B, N); 56 } 57 58 BIGNUM *SRP_Calc_server_key(const BIGNUM *A, const BIGNUM *v, const BIGNUM *u, 59 const BIGNUM *b, const BIGNUM *N) 60 { 61 BIGNUM *tmp = NULL, *S = NULL; 62 BN_CTX *bn_ctx; 63 64 if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL) 65 return NULL; 66 67 if ((bn_ctx = BN_CTX_new()) == NULL || (tmp = BN_new()) == NULL) 68 goto err; 69 70 /* S = (A*v**u) ** b */ 71 72 if (!BN_mod_exp(tmp, v, u, N, bn_ctx)) 73 goto err; 74 if (!BN_mod_mul(tmp, A, tmp, N, bn_ctx)) 75 goto err; 76 77 S = BN_new(); 78 if (S != NULL && !BN_mod_exp(S, tmp, b, N, bn_ctx)) { 79 BN_free(S); 80 S = NULL; 81 } 82 err: 83 BN_CTX_free(bn_ctx); 84 BN_clear_free(tmp); 85 return S; 86 } 87 88 BIGNUM *SRP_Calc_B(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g, 89 const BIGNUM *v) 90 { 91 BIGNUM *kv = NULL, *gb = NULL; 92 BIGNUM *B = NULL, *k = NULL; 93 BN_CTX *bn_ctx; 94 95 if (b == NULL || N == NULL || g == NULL || v == NULL || 96 (bn_ctx = BN_CTX_new()) == NULL) 97 return NULL; 98 99 if ((kv = BN_new()) == NULL || 100 (gb = BN_new()) == NULL || (B = BN_new()) == NULL) 101 goto err; 102 103 /* B = g**b + k*v */ 104 105 if (!BN_mod_exp(gb, g, b, N, bn_ctx) 106 || (k = srp_Calc_k(N, g)) == NULL 107 || !BN_mod_mul(kv, v, k, N, bn_ctx) 108 || !BN_mod_add(B, gb, kv, N, bn_ctx)) { 109 BN_free(B); 110 B = NULL; 111 } 112 err: 113 BN_CTX_free(bn_ctx); 114 BN_clear_free(kv); 115 BN_clear_free(gb); 116 BN_free(k); 117 return B; 118 } 119 120 BIGNUM *SRP_Calc_x(const BIGNUM *s, const char *user, const char *pass) 121 { 122 unsigned char dig[SHA_DIGEST_LENGTH]; 123 EVP_MD_CTX *ctxt; 124 unsigned char *cs = NULL; 125 BIGNUM *res = NULL; 126 127 if ((s == NULL) || (user == NULL) || (pass == NULL)) 128 return NULL; 129 130 ctxt = EVP_MD_CTX_new(); 131 if (ctxt == NULL) 132 return NULL; 133 if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL) 134 goto err; 135 136 if (!EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL) 137 || !EVP_DigestUpdate(ctxt, user, strlen(user)) 138 || !EVP_DigestUpdate(ctxt, ":", 1) 139 || !EVP_DigestUpdate(ctxt, pass, strlen(pass)) 140 || !EVP_DigestFinal_ex(ctxt, dig, NULL) 141 || !EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL)) 142 goto err; 143 if (BN_bn2bin(s, cs) < 0) 144 goto err; 145 if (!EVP_DigestUpdate(ctxt, cs, BN_num_bytes(s))) 146 goto err; 147 148 if (!EVP_DigestUpdate(ctxt, dig, sizeof(dig)) 149 || !EVP_DigestFinal_ex(ctxt, dig, NULL)) 150 goto err; 151 152 res = BN_bin2bn(dig, sizeof(dig), NULL); 153 154 err: 155 OPENSSL_free(cs); 156 EVP_MD_CTX_free(ctxt); 157 return res; 158 } 159 160 BIGNUM *SRP_Calc_A(const BIGNUM *a, const BIGNUM *N, const BIGNUM *g) 161 { 162 BN_CTX *bn_ctx; 163 BIGNUM *A = NULL; 164 165 if (a == NULL || N == NULL || g == NULL || (bn_ctx = BN_CTX_new()) == NULL) 166 return NULL; 167 168 if ((A = BN_new()) != NULL && !BN_mod_exp(A, g, a, N, bn_ctx)) { 169 BN_free(A); 170 A = NULL; 171 } 172 BN_CTX_free(bn_ctx); 173 return A; 174 } 175 176 BIGNUM *SRP_Calc_client_key(const BIGNUM *N, const BIGNUM *B, const BIGNUM *g, 177 const BIGNUM *x, const BIGNUM *a, const BIGNUM *u) 178 { 179 BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL, *k = NULL, *K = NULL; 180 BIGNUM *xtmp = NULL; 181 BN_CTX *bn_ctx; 182 183 if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL 184 || a == NULL || (bn_ctx = BN_CTX_new()) == NULL) 185 return NULL; 186 187 if ((tmp = BN_new()) == NULL || 188 (tmp2 = BN_new()) == NULL || 189 (tmp3 = BN_new()) == NULL || 190 (xtmp = BN_new()) == NULL) 191 goto err; 192 193 BN_with_flags(xtmp, x, BN_FLG_CONSTTIME); 194 BN_set_flags(tmp, BN_FLG_CONSTTIME); 195 if (!BN_mod_exp(tmp, g, xtmp, N, bn_ctx)) 196 goto err; 197 if ((k = srp_Calc_k(N, g)) == NULL) 198 goto err; 199 if (!BN_mod_mul(tmp2, tmp, k, N, bn_ctx)) 200 goto err; 201 if (!BN_mod_sub(tmp, B, tmp2, N, bn_ctx)) 202 goto err; 203 if (!BN_mul(tmp3, u, xtmp, bn_ctx)) 204 goto err; 205 if (!BN_add(tmp2, a, tmp3)) 206 goto err; 207 K = BN_new(); 208 if (K != NULL && !BN_mod_exp(K, tmp, tmp2, N, bn_ctx)) { 209 BN_free(K); 210 K = NULL; 211 } 212 213 err: 214 BN_CTX_free(bn_ctx); 215 BN_free(xtmp); 216 BN_clear_free(tmp); 217 BN_clear_free(tmp2); 218 BN_clear_free(tmp3); 219 BN_free(k); 220 return K; 221 } 222 223 int SRP_Verify_B_mod_N(const BIGNUM *B, const BIGNUM *N) 224 { 225 BIGNUM *r; 226 BN_CTX *bn_ctx; 227 int ret = 0; 228 229 if (B == NULL || N == NULL || (bn_ctx = BN_CTX_new()) == NULL) 230 return 0; 231 232 if ((r = BN_new()) == NULL) 233 goto err; 234 /* Checks if B % N == 0 */ 235 if (!BN_nnmod(r, B, N, bn_ctx)) 236 goto err; 237 ret = !BN_is_zero(r); 238 err: 239 BN_CTX_free(bn_ctx); 240 BN_free(r); 241 return ret; 242 } 243 244 int SRP_Verify_A_mod_N(const BIGNUM *A, const BIGNUM *N) 245 { 246 /* Checks if A % N == 0 */ 247 return SRP_Verify_B_mod_N(A, N); 248 } 249 250 static SRP_gN knowngN[] = { 251 {"8192", &bn_generator_19, &bn_group_8192}, 252 {"6144", &bn_generator_5, &bn_group_6144}, 253 {"4096", &bn_generator_5, &bn_group_4096}, 254 {"3072", &bn_generator_5, &bn_group_3072}, 255 {"2048", &bn_generator_2, &bn_group_2048}, 256 {"1536", &bn_generator_2, &bn_group_1536}, 257 {"1024", &bn_generator_2, &bn_group_1024}, 258 }; 259 260 # define KNOWN_GN_NUMBER sizeof(knowngN) / sizeof(SRP_gN) 261 262 /* 263 * Check if G and N are known parameters. The values have been generated 264 * from the ietf-tls-srp draft version 8 265 */ 266 char *SRP_check_known_gN_param(const BIGNUM *g, const BIGNUM *N) 267 { 268 size_t i; 269 if ((g == NULL) || (N == NULL)) 270 return 0; 271 272 for (i = 0; i < KNOWN_GN_NUMBER; i++) { 273 if (BN_cmp(knowngN[i].g, g) == 0 && BN_cmp(knowngN[i].N, N) == 0) 274 return knowngN[i].id; 275 } 276 return NULL; 277 } 278 279 SRP_gN *SRP_get_default_gN(const char *id) 280 { 281 size_t i; 282 283 if (id == NULL) 284 return knowngN; 285 for (i = 0; i < KNOWN_GN_NUMBER; i++) { 286 if (strcmp(knowngN[i].id, id) == 0) 287 return knowngN + i; 288 } 289 return NULL; 290 } 291 #endif 292