srp_lib.c 9.0 KB

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