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