sha.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*
  2. * $Id$
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. *
  18. * Gabber
  19. * Copyright (C) 1999-2000 Dave Smith & Julian Missig
  20. *
  21. */
  22. /*! \file
  23. * \ingroup xmpp
  24. */
  25. /*
  26. Implements the Secure Hash Algorithm (SHA1)
  27. Copyright (C) 1999 Scott G. Miller
  28. Released under the terms of the GNU General Public License v2
  29. see file COPYING for details
  30. Credits:
  31. Robert Klep <[email protected]> -- Expansion function fix
  32. Thomas "temas" Muldowney <[email protected]>:
  33. -- shahash() for string fun
  34. -- Will add the int32 stuff in a few
  35. ---
  36. FIXME: This source takes int to be a 32 bit integer. This
  37. may vary from system to system. I'd use autoconf if I was familiar
  38. with it. Anyone want to help me out?
  39. */
  40. //#include <config.h>
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <fcntl.h>
  44. #include <string.h>
  45. #ifndef MACOS
  46. # include <sys/stat.h>
  47. # include <sys/types.h>
  48. #endif
  49. #ifndef WIN32
  50. # include <unistd.h>
  51. # define INT64 long long
  52. #else
  53. # define snprintf _snprintf
  54. # define INT64 __int64
  55. #endif
  56. #define switch_endianness(x) (x<<24 & 0xff000000) | \
  57. (x<<8 & 0x00ff0000) | \
  58. (x>>8 & 0x0000ff00) | \
  59. (x>>24 & 0x000000ff)
  60. /* Initial hash values */
  61. #define Ai 0x67452301
  62. #define Bi 0xefcdab89
  63. #define Ci 0x98badcfe
  64. #define Di 0x10325476
  65. #define Ei 0xc3d2e1f0
  66. /* SHA1 round constants */
  67. #define K1 0x5a827999
  68. #define K2 0x6ed9eba1
  69. #define K3 0x8f1bbcdc
  70. #define K4 0xca62c1d6
  71. /* Round functions. Note that f2() is used in both rounds 2 and 4 */
  72. #define f1(B,C,D) ((B & C) | ((~B) & D))
  73. #define f2(B,C,D) (B ^ C ^ D)
  74. #define f3(B,C,D) ((B & C) | (B & D) | (C & D))
  75. /* left circular shift functions (rotate left) */
  76. #define rol1(x) ((x<<1) | ((x>>31) & 1))
  77. #define rol5(A) ((A<<5) | ((A>>27) & 0x1f))
  78. #define rol30(B) ((B<<30) | ((B>>2) & 0x3fffffff))
  79. /*
  80. Hashes 'data', which should be a pointer to 512 bits of data (sixteen
  81. 32 bit ints), into the ongoing 160 bit hash value (five 32 bit ints)
  82. 'hash'
  83. */
  84. int
  85. sha_hash(int *data, int *hash)
  86. {
  87. int W[80];
  88. unsigned int A=hash[0], B=hash[1], C=hash[2], D=hash[3], E=hash[4];
  89. unsigned int t, x, TEMP;
  90. for (t=0; t<16; t++)
  91. {
  92. #ifndef WORDS_BIGENDIAN
  93. W[t]=switch_endianness(data[t]);
  94. #else
  95. W[t]=data[t];
  96. #endif
  97. }
  98. /* SHA1 Data expansion */
  99. for (t=16; t<80; t++)
  100. {
  101. x=W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
  102. W[t]=rol1(x);
  103. }
  104. /* SHA1 main loop (t=0 to 79)
  105. This is broken down into four subloops in order to use
  106. the correct round function and constant */
  107. for (t=0; t<20; t++)
  108. {
  109. TEMP=rol5(A) + f1(B,C,D) + E + W[t] + K1;
  110. E=D;
  111. D=C;
  112. C=rol30(B);
  113. B=A;
  114. A=TEMP;
  115. }
  116. for (; t<40; t++)
  117. {
  118. TEMP=rol5(A) + f2(B,C,D) + E + W[t] + K2;
  119. E=D;
  120. D=C;
  121. C=rol30(B);
  122. B=A;
  123. A=TEMP;
  124. }
  125. for (; t<60; t++)
  126. {
  127. TEMP=rol5(A) + f3(B,C,D) + E + W[t] + K3;
  128. E=D;
  129. D=C;
  130. C=rol30(B);
  131. B=A;
  132. A=TEMP;
  133. }
  134. for (; t<80; t++)
  135. {
  136. TEMP=rol5(A) + f2(B,C,D) + E + W[t] + K4;
  137. E=D;
  138. D=C;
  139. C=rol30(B);
  140. B=A;
  141. A=TEMP;
  142. }
  143. hash[0]+=A;
  144. hash[1]+=B;
  145. hash[2]+=C;
  146. hash[3]+=D;
  147. hash[4]+=E;
  148. return 0;
  149. }
  150. /*
  151. Takes a pointer to a 160 bit block of data (five 32 bit ints) and
  152. initializes it to the start constants of the SHA1 algorithm. This
  153. must be called before using hash in the call to sha_hash
  154. */
  155. int
  156. sha_init(int *hash)
  157. {
  158. hash[0]=Ai;
  159. hash[1]=Bi;
  160. hash[2]=Ci;
  161. hash[3]=Di;
  162. hash[4]=Ei;
  163. return 0;
  164. }
  165. int strprintsha(char *dest, int *hashval)
  166. {
  167. int x;
  168. char *hashstr = dest;
  169. for (x=0; x<5; x++)
  170. {
  171. snprintf(hashstr, 9, "%08x", hashval[x]);
  172. hashstr+=8;
  173. }
  174. /*old way */
  175. //snprintf(hashstr++, 1, "\0");
  176. /*new way - by bogdan*/
  177. *hashstr = 0;
  178. return 0;
  179. }
  180. char *shahash(const char *str)
  181. {
  182. char read_buffer[65];
  183. //int read_buffer[64];
  184. int c=1, i;
  185. INT64 length=0;
  186. int strsz;
  187. static char final[40];
  188. int *hashval;
  189. hashval = (int *)malloc(20);
  190. sha_init(hashval);
  191. strsz = strlen(str);
  192. if(strsz == 0)
  193. {
  194. memset(read_buffer, 0, 65);
  195. read_buffer[0] = 0x80;
  196. sha_hash((int *)read_buffer, hashval);
  197. }
  198. while (strsz>0)
  199. {
  200. memset(read_buffer, 0, 65);
  201. strncpy((char*)read_buffer, str, 64);
  202. c = strlen((char *)read_buffer);
  203. length+=c;
  204. strsz-=c;
  205. if (strsz<=0)
  206. {
  207. length<<=3;
  208. read_buffer[c]=(char)0x80;
  209. for (i=c+1; i<64; i++)
  210. read_buffer[i]=0;
  211. if (c>55)
  212. {
  213. /* we need to do an entire new block */
  214. sha_hash((int *)read_buffer, hashval);
  215. for (i=0; i<14; i++)
  216. ((int*)read_buffer)[i]=0;
  217. }
  218. #ifndef WORDS_BIGENDIAN
  219. for (i=0; i<8; i++)
  220. {
  221. read_buffer[56+i]=(char)(length>>(56-(i*8))) & 0xff;
  222. }
  223. #else
  224. memcpy(read_buffer+56, &length, 8);
  225. #endif
  226. }
  227. sha_hash((int *)read_buffer, hashval);
  228. str+=64;
  229. }
  230. strprintsha((char *)final, hashval);
  231. free(hashval);
  232. return (char *)final;
  233. }