srp_lib.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  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. #if (BN_BYTES == 8)
  65. # if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
  66. # define bn_pack4(a1,a2,a3,a4) 0x##a1##a2##a3##a4##UI64
  67. # elif defined(__arch64__)
  68. # define bn_pack4(a1,a2,a3,a4) 0x##a1##a2##a3##a4##UL
  69. # else
  70. # define bn_pack4(a1,a2,a3,a4) 0x##a1##a2##a3##a4##ULL
  71. # endif
  72. #elif (BN_BYTES == 4)
  73. # define bn_pack4(a1,a2,a3,a4) 0x##a3##a4##UL, 0x##a1##a2##UL
  74. #else
  75. # error "unsupported BN_BYTES"
  76. #endif
  77. #include "srp_grps.h"
  78. static BIGNUM *srp_Calc_k(BIGNUM *N, BIGNUM *g)
  79. {
  80. /* k = SHA1(N | PAD(g)) -- tls-srp draft 8 */
  81. unsigned char digest[SHA_DIGEST_LENGTH];
  82. unsigned char *tmp;
  83. EVP_MD_CTX ctxt;
  84. int longg ;
  85. int longN = BN_num_bytes(N);
  86. if ((tmp = OPENSSL_malloc(longN)) == NULL)
  87. return NULL;
  88. BN_bn2bin(N,tmp) ;
  89. EVP_MD_CTX_init(&ctxt);
  90. EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
  91. EVP_DigestUpdate(&ctxt, tmp, longN);
  92. memset(tmp, 0, longN);
  93. longg = BN_bn2bin(g,tmp) ;
  94. /* use the zeros behind to pad on left */
  95. EVP_DigestUpdate(&ctxt, tmp + longg, longN-longg);
  96. EVP_DigestUpdate(&ctxt, tmp, longg);
  97. OPENSSL_free(tmp);
  98. EVP_DigestFinal_ex(&ctxt, digest, NULL);
  99. EVP_MD_CTX_cleanup(&ctxt);
  100. return BN_bin2bn(digest, sizeof(digest), NULL);
  101. }
  102. BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N)
  103. {
  104. /* k = SHA1(PAD(A) || PAD(B) ) -- tls-srp draft 8 */
  105. BIGNUM *u;
  106. unsigned char cu[SHA_DIGEST_LENGTH];
  107. unsigned char *cAB;
  108. EVP_MD_CTX ctxt;
  109. int longN;
  110. if ((A == NULL) ||(B == NULL) || (N == NULL))
  111. return NULL;
  112. longN= BN_num_bytes(N);
  113. if ((cAB = OPENSSL_malloc(2*longN)) == NULL)
  114. return NULL;
  115. memset(cAB, 0, longN);
  116. EVP_MD_CTX_init(&ctxt);
  117. EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
  118. EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(A,cAB+longN), longN);
  119. EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(B,cAB+longN), longN);
  120. OPENSSL_free(cAB);
  121. EVP_DigestFinal_ex(&ctxt, cu, NULL);
  122. EVP_MD_CTX_cleanup(&ctxt);
  123. if (!(u = BN_bin2bn(cu, sizeof(cu), NULL)))
  124. return NULL;
  125. if (!BN_is_zero(u))
  126. return u;
  127. BN_free(u);
  128. return NULL;
  129. }
  130. BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, BIGNUM *N)
  131. {
  132. BIGNUM *tmp = NULL, *S = NULL;
  133. BN_CTX *bn_ctx;
  134. if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL)
  135. return NULL;
  136. if ((bn_ctx = BN_CTX_new()) == NULL ||
  137. (tmp = BN_new()) == NULL ||
  138. (S = BN_new()) == NULL )
  139. goto err;
  140. /* S = (A*v**u) ** b */
  141. if (!BN_mod_exp(tmp,v,u,N,bn_ctx))
  142. goto err;
  143. if (!BN_mod_mul(tmp,A,tmp,N,bn_ctx))
  144. goto err;
  145. if (!BN_mod_exp(S,tmp,b,N,bn_ctx))
  146. goto err;
  147. err:
  148. BN_CTX_free(bn_ctx);
  149. BN_clear_free(tmp);
  150. return S;
  151. }
  152. BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v)
  153. {
  154. BIGNUM *kv = NULL, *gb = NULL;
  155. BIGNUM *B = NULL, *k = NULL;
  156. BN_CTX *bn_ctx;
  157. if (b == NULL || N == NULL || g == NULL || v == NULL ||
  158. (bn_ctx = BN_CTX_new()) == NULL)
  159. return NULL;
  160. if ( (kv = BN_new()) == NULL ||
  161. (gb = BN_new()) == NULL ||
  162. (B = BN_new())== NULL)
  163. goto err;
  164. /* B = g**b + k*v */
  165. if (!BN_mod_exp(gb,g,b,N,bn_ctx) ||
  166. !(k = srp_Calc_k(N,g)) ||
  167. !BN_mod_mul(kv,v,k,N,bn_ctx) ||
  168. !BN_mod_add(B,gb,kv,N,bn_ctx))
  169. {
  170. BN_free(B);
  171. B = NULL;
  172. }
  173. err:
  174. BN_CTX_free(bn_ctx);
  175. BN_clear_free(kv);
  176. BN_clear_free(gb);
  177. BN_free(k);
  178. return B;
  179. }
  180. BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass)
  181. {
  182. unsigned char dig[SHA_DIGEST_LENGTH];
  183. EVP_MD_CTX ctxt;
  184. unsigned char *cs;
  185. if ((s == NULL) ||
  186. (user == NULL) ||
  187. (pass == NULL))
  188. return NULL;
  189. if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL)
  190. return NULL;
  191. EVP_MD_CTX_init(&ctxt);
  192. EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
  193. EVP_DigestUpdate(&ctxt, user, strlen(user));
  194. EVP_DigestUpdate(&ctxt, ":", 1);
  195. EVP_DigestUpdate(&ctxt, pass, strlen(pass));
  196. EVP_DigestFinal_ex(&ctxt, dig, NULL);
  197. EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
  198. BN_bn2bin(s,cs);
  199. EVP_DigestUpdate(&ctxt, cs, BN_num_bytes(s));
  200. OPENSSL_free(cs);
  201. EVP_DigestUpdate(&ctxt, dig, sizeof(dig));
  202. EVP_DigestFinal_ex(&ctxt, dig, NULL);
  203. EVP_MD_CTX_cleanup(&ctxt);
  204. return BN_bin2bn(dig, sizeof(dig), NULL);
  205. }
  206. BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g)
  207. {
  208. BN_CTX *bn_ctx;
  209. BIGNUM * A = NULL;
  210. if (a == NULL || N == NULL || g == NULL ||
  211. (bn_ctx = BN_CTX_new()) == NULL)
  212. return NULL;
  213. if ((A = BN_new()) != NULL &&
  214. !BN_mod_exp(A,g,a,N,bn_ctx))
  215. {
  216. BN_free(A);
  217. A = NULL;
  218. }
  219. BN_CTX_free(bn_ctx);
  220. return A;
  221. }
  222. BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, BIGNUM *a, BIGNUM *u)
  223. {
  224. BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL , *k = NULL, *K = NULL;
  225. BN_CTX *bn_ctx;
  226. if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL || a == NULL ||
  227. (bn_ctx = BN_CTX_new()) == NULL)
  228. return NULL;
  229. if ((tmp = BN_new()) == NULL ||
  230. (tmp2 = BN_new())== NULL ||
  231. (tmp3 = BN_new())== NULL ||
  232. (K = BN_new()) == NULL)
  233. goto err;
  234. if (!BN_mod_exp(tmp,g,x,N,bn_ctx))
  235. goto err;
  236. if (!(k = srp_Calc_k(N,g)))
  237. goto err;
  238. if (!BN_mod_mul(tmp2,tmp,k,N,bn_ctx))
  239. goto err;
  240. if (!BN_mod_sub(tmp,B,tmp2,N,bn_ctx))
  241. goto err;
  242. if (!BN_mod_mul(tmp3,u,x,N,bn_ctx))
  243. goto err;
  244. if (!BN_mod_add(tmp2,a,tmp3,N,bn_ctx))
  245. goto err;
  246. if (!BN_mod_exp(K,tmp,tmp2,N,bn_ctx))
  247. goto err;
  248. err :
  249. BN_CTX_free(bn_ctx);
  250. BN_clear_free(tmp);
  251. BN_clear_free(tmp2);
  252. BN_clear_free(tmp3);
  253. BN_free(k);
  254. return K;
  255. }
  256. int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N)
  257. {
  258. BIGNUM *r;
  259. BN_CTX *bn_ctx;
  260. int ret = 0;
  261. if (B == NULL || N == NULL ||
  262. (bn_ctx = BN_CTX_new()) == NULL)
  263. return 0;
  264. if ((r = BN_new()) == NULL)
  265. goto err;
  266. /* Checks if B % N == 0 */
  267. if (!BN_nnmod(r,B,N,bn_ctx))
  268. goto err;
  269. ret = !BN_is_zero(r);
  270. err:
  271. BN_CTX_free(bn_ctx);
  272. BN_free(r);
  273. return ret;
  274. }
  275. int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N)
  276. {
  277. /* Checks if A % N == 0 */
  278. return SRP_Verify_B_mod_N(A,N) ;
  279. }
  280. /* Check if G and N are kwown parameters.
  281. The values have been generated from the ietf-tls-srp draft version 8
  282. */
  283. char * SRP_check_known_gN_param(BIGNUM* g, BIGNUM* N)
  284. {
  285. size_t i;
  286. if ((g == NULL) || (N == NULL))
  287. return 0;
  288. srp_bn_print(g);
  289. srp_bn_print(N);
  290. for(i = 0; i < KNOWN_GN_NUMBER; i++)
  291. {
  292. if (BN_cmp(knowngN[i].g,g) == 0 && BN_cmp(knowngN[i].N,N) == 0)
  293. return knowngN[i].id;
  294. }
  295. return NULL;
  296. }
  297. SRP_gN *SRP_get_default_gN(const char * id)
  298. {
  299. size_t i;
  300. if (id == NULL)
  301. return knowngN;
  302. for(i = 0; i < KNOWN_GN_NUMBER; i++)
  303. {
  304. if (strcmp(knowngN[i].id,id)==0)
  305. return knowngN+i;
  306. }
  307. return NULL;
  308. }
  309. #endif