1 /* 2 * Copyright 2004-2019 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 "internal/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 BN_CTX *bn_ctx; 181 182 if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL 183 || a == NULL || (bn_ctx = BN_CTX_new()) == NULL) 184 return NULL; 185 186 if ((tmp = BN_new()) == NULL || 187 (tmp2 = BN_new()) == NULL || 188 (tmp3 = BN_new()) == NULL) 189 goto err; 190 191 if (!BN_mod_exp(tmp, g, x, N, bn_ctx)) 192 goto err; 193 if ((k = srp_Calc_k(N, g)) == NULL) 194 goto err; 195 if (!BN_mod_mul(tmp2, tmp, k, N, bn_ctx)) 196 goto err; 197 if (!BN_mod_sub(tmp, B, tmp2, N, bn_ctx)) 198 goto err; 199 if (!BN_mul(tmp3, u, x, bn_ctx)) 200 goto err; 201 if (!BN_add(tmp2, a, tmp3)) 202 goto err; 203 K = BN_new(); 204 if (K != NULL && !BN_mod_exp(K, tmp, tmp2, N, bn_ctx)) { 205 BN_free(K); 206 K = NULL; 207 } 208 209 err: 210 BN_CTX_free(bn_ctx); 211 BN_clear_free(tmp); 212 BN_clear_free(tmp2); 213 BN_clear_free(tmp3); 214 BN_free(k); 215 return K; 216 } 217 218 int SRP_Verify_B_mod_N(const BIGNUM *B, const BIGNUM *N) 219 { 220 BIGNUM *r; 221 BN_CTX *bn_ctx; 222 int ret = 0; 223 224 if (B == NULL || N == NULL || (bn_ctx = BN_CTX_new()) == NULL) 225 return 0; 226 227 if ((r = BN_new()) == NULL) 228 goto err; 229 /* Checks if B % N == 0 */ 230 if (!BN_nnmod(r, B, N, bn_ctx)) 231 goto err; 232 ret = !BN_is_zero(r); 233 err: 234 BN_CTX_free(bn_ctx); 235 BN_free(r); 236 return ret; 237 } 238 239 int SRP_Verify_A_mod_N(const BIGNUM *A, const BIGNUM *N) 240 { 241 /* Checks if A % N == 0 */ 242 return SRP_Verify_B_mod_N(A, N); 243 } 244 245 static SRP_gN knowngN[] = { 246 {"8192", &bn_generator_19, &bn_group_8192}, 247 {"6144", &bn_generator_5, &bn_group_6144}, 248 {"4096", &bn_generator_5, &bn_group_4096}, 249 {"3072", &bn_generator_5, &bn_group_3072}, 250 {"2048", &bn_generator_2, &bn_group_2048}, 251 {"1536", &bn_generator_2, &bn_group_1536}, 252 {"1024", &bn_generator_2, &bn_group_1024}, 253 }; 254 255 # define KNOWN_GN_NUMBER sizeof(knowngN) / sizeof(SRP_gN) 256 257 /* 258 * Check if G and N are known parameters. The values have been generated 259 * from the ietf-tls-srp draft version 8 260 */ 261 char *SRP_check_known_gN_param(const BIGNUM *g, const BIGNUM *N) 262 { 263 size_t i; 264 if ((g == NULL) || (N == NULL)) 265 return 0; 266 267 for (i = 0; i < KNOWN_GN_NUMBER; i++) { 268 if (BN_cmp(knowngN[i].g, g) == 0 && BN_cmp(knowngN[i].N, N) == 0) 269 return knowngN[i].id; 270 } 271 return NULL; 272 } 273 274 SRP_gN *SRP_get_default_gN(const char *id) 275 { 276 size_t i; 277 278 if (id == NULL) 279 return knowngN; 280 for (i = 0; i < KNOWN_GN_NUMBER; i++) { 281 if (strcmp(knowngN[i].id, id) == 0) 282 return knowngN + i; 283 } 284 return NULL; 285 } 286 #endif 287