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