srp_lib.c revision 271304
1/* crypto/srp/srp_lib.c */ 2/* Written by Christophe Renou (christophe.renou@edelweb.fr) with 3 * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr) 4 * for the EdelKey project and contributed to the OpenSSL project 2004. 5 */ 6/* ==================================================================== 7 * Copyright (c) 2004 The OpenSSL Project. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. All advertising materials mentioning features or use of this 22 * software must display the following acknowledgment: 23 * "This product includes software developed by the OpenSSL Project 24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25 * 26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27 * endorse or promote products derived from this software without 28 * prior written permission. For written permission, please contact 29 * licensing@OpenSSL.org. 30 * 31 * 5. Products derived from this software may not be called "OpenSSL" 32 * nor may "OpenSSL" appear in their names without prior written 33 * permission of the OpenSSL Project. 34 * 35 * 6. Redistributions of any form whatsoever must retain the following 36 * acknowledgment: 37 * "This product includes software developed by the OpenSSL Project 38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51 * OF THE POSSIBILITY OF SUCH DAMAGE. 52 * ==================================================================== 53 * 54 * This product includes cryptographic software written by Eric Young 55 * (eay@cryptsoft.com). This product includes software written by Tim 56 * Hudson (tjh@cryptsoft.com). 57 * 58 */ 59#ifndef OPENSSL_NO_SRP 60#include "cryptlib.h" 61#include "srp_lcl.h" 62#include <openssl/srp.h> 63#include <openssl/evp.h> 64 65#if (BN_BYTES == 8) 66#define bn_pack4(a1,a2,a3,a4) 0x##a1##a2##a3##a4##ul 67#endif 68#if (BN_BYTES == 4) 69#define bn_pack4(a1,a2,a3,a4) 0x##a3##a4##ul, 0x##a1##a2##ul 70#endif 71#if (BN_BYTES == 2) 72#define bn_pack4(a1,a2,a3,a4) 0x##a4##u,0x##a3##u,0x##a2##u,0x##a1##u 73#endif 74 75 76#include "srp_grps.h" 77 78static BIGNUM *srp_Calc_k(BIGNUM *N, BIGNUM *g) 79 { 80 /* k = SHA1(N | PAD(g)) -- tls-srp draft 8 */ 81 82 unsigned char digest[SHA_DIGEST_LENGTH]; 83 unsigned char *tmp; 84 EVP_MD_CTX ctxt; 85 int longg ; 86 int longN = BN_num_bytes(N); 87 88 if (BN_ucmp(g, N) >= 0) 89 return NULL; 90 91 if ((tmp = OPENSSL_malloc(longN)) == NULL) 92 return NULL; 93 BN_bn2bin(N,tmp) ; 94 95 EVP_MD_CTX_init(&ctxt); 96 EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); 97 EVP_DigestUpdate(&ctxt, tmp, longN); 98 99 memset(tmp, 0, longN); 100 longg = BN_bn2bin(g,tmp) ; 101 /* use the zeros behind to pad on left */ 102 EVP_DigestUpdate(&ctxt, tmp + longg, longN-longg); 103 EVP_DigestUpdate(&ctxt, tmp, longg); 104 OPENSSL_free(tmp); 105 106 EVP_DigestFinal_ex(&ctxt, digest, NULL); 107 EVP_MD_CTX_cleanup(&ctxt); 108 return BN_bin2bn(digest, sizeof(digest), NULL); 109 } 110 111BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N) 112 { 113 /* k = SHA1(PAD(A) || PAD(B) ) -- tls-srp draft 8 */ 114 115 BIGNUM *u; 116 unsigned char cu[SHA_DIGEST_LENGTH]; 117 unsigned char *cAB; 118 EVP_MD_CTX ctxt; 119 int longN; 120 if ((A == NULL) ||(B == NULL) || (N == NULL)) 121 return NULL; 122 123 if (BN_ucmp(A, N) >= 0 || BN_ucmp(B, N) >= 0) 124 return NULL; 125 126 longN= BN_num_bytes(N); 127 128 if ((cAB = OPENSSL_malloc(2*longN)) == NULL) 129 return NULL; 130 131 memset(cAB, 0, longN); 132 133 EVP_MD_CTX_init(&ctxt); 134 EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); 135 EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(A,cAB+longN), longN); 136 EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(B,cAB+longN), longN); 137 OPENSSL_free(cAB); 138 EVP_DigestFinal_ex(&ctxt, cu, NULL); 139 EVP_MD_CTX_cleanup(&ctxt); 140 141 if (!(u = BN_bin2bn(cu, sizeof(cu), NULL))) 142 return NULL; 143 if (!BN_is_zero(u)) 144 return u; 145 BN_free(u); 146 return NULL; 147} 148 149BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, BIGNUM *N) 150 { 151 BIGNUM *tmp = NULL, *S = NULL; 152 BN_CTX *bn_ctx; 153 154 if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL) 155 return NULL; 156 157 if ((bn_ctx = BN_CTX_new()) == NULL || 158 (tmp = BN_new()) == NULL || 159 (S = BN_new()) == NULL ) 160 goto err; 161 162 /* S = (A*v**u) ** b */ 163 164 if (!BN_mod_exp(tmp,v,u,N,bn_ctx)) 165 goto err; 166 if (!BN_mod_mul(tmp,A,tmp,N,bn_ctx)) 167 goto err; 168 if (!BN_mod_exp(S,tmp,b,N,bn_ctx)) 169 goto err; 170err: 171 BN_CTX_free(bn_ctx); 172 BN_clear_free(tmp); 173 return S; 174 } 175 176BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v) 177 { 178 BIGNUM *kv = NULL, *gb = NULL; 179 BIGNUM *B = NULL, *k = NULL; 180 BN_CTX *bn_ctx; 181 182 if (b == NULL || N == NULL || g == NULL || v == NULL || 183 (bn_ctx = BN_CTX_new()) == NULL) 184 return NULL; 185 186 if ( (kv = BN_new()) == NULL || 187 (gb = BN_new()) == NULL || 188 (B = BN_new())== NULL) 189 goto err; 190 191 /* B = g**b + k*v */ 192 193 if (!BN_mod_exp(gb,g,b,N,bn_ctx) || 194 !(k = srp_Calc_k(N,g)) || 195 !BN_mod_mul(kv,v,k,N,bn_ctx) || 196 !BN_mod_add(B,gb,kv,N,bn_ctx)) 197 { 198 BN_free(B); 199 B = NULL; 200 } 201err: 202 BN_CTX_free(bn_ctx); 203 BN_clear_free(kv); 204 BN_clear_free(gb); 205 BN_free(k); 206 return B; 207 } 208 209BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass) 210 { 211 unsigned char dig[SHA_DIGEST_LENGTH]; 212 EVP_MD_CTX ctxt; 213 unsigned char *cs; 214 215 if ((s == NULL) || 216 (user == NULL) || 217 (pass == NULL)) 218 return NULL; 219 220 if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL) 221 return NULL; 222 223 EVP_MD_CTX_init(&ctxt); 224 EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); 225 EVP_DigestUpdate(&ctxt, user, strlen(user)); 226 EVP_DigestUpdate(&ctxt, ":", 1); 227 EVP_DigestUpdate(&ctxt, pass, strlen(pass)); 228 EVP_DigestFinal_ex(&ctxt, dig, NULL); 229 230 EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); 231 BN_bn2bin(s,cs); 232 EVP_DigestUpdate(&ctxt, cs, BN_num_bytes(s)); 233 OPENSSL_free(cs); 234 EVP_DigestUpdate(&ctxt, dig, sizeof(dig)); 235 EVP_DigestFinal_ex(&ctxt, dig, NULL); 236 EVP_MD_CTX_cleanup(&ctxt); 237 238 return BN_bin2bn(dig, sizeof(dig), NULL); 239 } 240 241BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g) 242 { 243 BN_CTX *bn_ctx; 244 BIGNUM * A = NULL; 245 246 if (a == NULL || N == NULL || g == NULL || 247 (bn_ctx = BN_CTX_new()) == NULL) 248 return NULL; 249 250 if ((A = BN_new()) != NULL && 251 !BN_mod_exp(A,g,a,N,bn_ctx)) 252 { 253 BN_free(A); 254 A = NULL; 255 } 256 BN_CTX_free(bn_ctx); 257 return A; 258 } 259 260 261BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, BIGNUM *a, BIGNUM *u) 262 { 263 BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL , *k = NULL, *K = NULL; 264 BN_CTX *bn_ctx; 265 266 if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL || a == NULL || 267 (bn_ctx = BN_CTX_new()) == NULL) 268 return NULL; 269 270 if ((tmp = BN_new()) == NULL || 271 (tmp2 = BN_new())== NULL || 272 (tmp3 = BN_new())== NULL || 273 (K = BN_new()) == NULL) 274 goto err; 275 276 if (!BN_mod_exp(tmp,g,x,N,bn_ctx)) 277 goto err; 278 if (!(k = srp_Calc_k(N,g))) 279 goto err; 280 if (!BN_mod_mul(tmp2,tmp,k,N,bn_ctx)) 281 goto err; 282 if (!BN_mod_sub(tmp,B,tmp2,N,bn_ctx)) 283 goto err; 284 285 if (!BN_mod_mul(tmp3,u,x,N,bn_ctx)) 286 goto err; 287 if (!BN_mod_add(tmp2,a,tmp3,N,bn_ctx)) 288 goto err; 289 if (!BN_mod_exp(K,tmp,tmp2,N,bn_ctx)) 290 goto err; 291 292err : 293 BN_CTX_free(bn_ctx); 294 BN_clear_free(tmp); 295 BN_clear_free(tmp2); 296 BN_clear_free(tmp3); 297 BN_free(k); 298 return K; 299 } 300 301int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N) 302 { 303 BIGNUM *r; 304 BN_CTX *bn_ctx; 305 int ret = 0; 306 307 if (B == NULL || N == NULL || 308 (bn_ctx = BN_CTX_new()) == NULL) 309 return 0; 310 311 if ((r = BN_new()) == NULL) 312 goto err; 313 /* Checks if B % N == 0 */ 314 if (!BN_nnmod(r,B,N,bn_ctx)) 315 goto err; 316 ret = !BN_is_zero(r); 317err: 318 BN_CTX_free(bn_ctx); 319 BN_free(r); 320 return ret; 321 } 322 323int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N) 324 { 325 /* Checks if A % N == 0 */ 326 return SRP_Verify_B_mod_N(A,N) ; 327 } 328 329 330/* Check if G and N are kwown parameters. 331 The values have been generated from the ietf-tls-srp draft version 8 332*/ 333char *SRP_check_known_gN_param(BIGNUM *g, BIGNUM *N) 334 { 335 size_t i; 336 if ((g == NULL) || (N == NULL)) 337 return 0; 338 339 srp_bn_print(g); 340 srp_bn_print(N); 341 342 for(i = 0; i < KNOWN_GN_NUMBER; i++) 343 { 344 if (BN_cmp(knowngN[i].g, g) == 0 && BN_cmp(knowngN[i].N, N) == 0) 345 return knowngN[i].id; 346 } 347 return NULL; 348 } 349 350SRP_gN *SRP_get_default_gN(const char *id) 351 { 352 size_t i; 353 354 if (id == NULL) 355 return knowngN; 356 for(i = 0; i < KNOWN_GN_NUMBER; i++) 357 { 358 if (strcmp(knowngN[i].id, id)==0) 359 return knowngN + i; 360 } 361 return NULL; 362 } 363#endif 364