sha.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /* iksemel (XML parser for Jabber)
  2. ** Copyright (C) 2000-2003 Gurer Ozen <madcat@e-kolay.net>
  3. ** This code is free software; you can redistribute it and/or
  4. ** modify it under the terms of GNU Lesser General Public License.
  5. */
  6. #include "common.h"
  7. #include "iksemel.h"
  8. static void sha_buffer (iksha *sha, const unsigned char *data, int len);
  9. static void sha_calculate (iksha *sha);
  10. struct iksha_struct {
  11. unsigned int hash[5];
  12. unsigned int buf[80];
  13. int blen;
  14. unsigned int lenhi, lenlo;
  15. };
  16. iksha *
  17. iks_sha_new (void)
  18. {
  19. iksha *sha;
  20. sha = iks_malloc (sizeof (iksha));
  21. if (!sha) return NULL;
  22. iks_sha_reset (sha);
  23. return sha;
  24. }
  25. void
  26. iks_sha_reset (iksha *sha)
  27. {
  28. memset (sha, 0, sizeof (iksha));
  29. sha->hash[0] = 0x67452301;
  30. sha->hash[1] = 0xefcdab89;
  31. sha->hash[2] = 0x98badcfe;
  32. sha->hash[3] = 0x10325476;
  33. sha->hash[4] = 0xc3d2e1f0;
  34. }
  35. void
  36. iks_sha_hash (iksha *sha, const unsigned char *data, size_t len, int finish)
  37. {
  38. unsigned char pad[8];
  39. unsigned char padc;
  40. if (data && len != 0) sha_buffer (sha, data, len);
  41. if (!finish) return;
  42. pad[0] = (unsigned char)((sha->lenhi >> 24) & 0xff);
  43. pad[1] = (unsigned char)((sha->lenhi >> 16) & 0xff);
  44. pad[2] = (unsigned char)((sha->lenhi >> 8) & 0xff);
  45. pad[3] = (unsigned char)(sha->lenhi & 0xff);
  46. pad[4] = (unsigned char)((sha->lenlo >> 24) & 0xff);
  47. pad[5] = (unsigned char)((sha->lenlo >> 16) & 0xff);
  48. pad[6] = (unsigned char)((sha->lenlo >> 8) & 0xff);
  49. pad[7] = (unsigned char)(sha->lenlo & 255);
  50. padc = 0x80;
  51. sha_buffer (sha, &padc, 1);
  52. padc = 0x00;
  53. while (sha->blen != 56)
  54. sha_buffer (sha, &padc, 1);
  55. sha_buffer (sha, pad, 8);
  56. }
  57. void
  58. iks_sha_print (iksha *sha, char *hash)
  59. {
  60. int i;
  61. for (i=0; i<5; i++)
  62. {
  63. sprintf (hash, "%08x", sha->hash[i]);
  64. hash += 8;
  65. }
  66. }
  67. void
  68. iks_sha_delete (iksha *sha)
  69. {
  70. iks_free (sha);
  71. }
  72. void
  73. iks_sha (const char *data, char *hash)
  74. {
  75. iksha *sha;
  76. sha = iks_sha_new ();
  77. iks_sha_hash (sha, (const unsigned char*)data, strlen (data), 1);
  78. iks_sha_print (sha, hash);
  79. iks_free (sha);
  80. }
  81. static void
  82. sha_buffer (iksha *sha, const unsigned char *data, int len)
  83. {
  84. int i;
  85. for (i=0; i<len; i++) {
  86. sha->buf[sha->blen / 4] <<= 8;
  87. sha->buf[sha->blen / 4] |= (unsigned int)data[i];
  88. if ((++sha->blen) % 64 == 0) {
  89. sha_calculate (sha);
  90. sha->blen = 0;
  91. }
  92. sha->lenlo += 8;
  93. sha->lenhi += (sha->lenlo < 8);
  94. }
  95. }
  96. #define SRL(x,y) (((x) << (y)) | ((x) >> (32-(y))))
  97. #define SHA(a,b,f,c) \
  98. for (i= (a) ; i<= (b) ; i++) { \
  99. TMP = SRL(A,5) + ( (f) ) + E + sha->buf[i] + (c) ; \
  100. E = D; \
  101. D = C; \
  102. C = SRL(B,30); \
  103. B = A; \
  104. A = TMP; \
  105. }
  106. static void
  107. sha_calculate (iksha *sha)
  108. {
  109. int i;
  110. unsigned int A, B, C, D, E, TMP;
  111. for (i=16; i<80; i++)
  112. sha->buf[i] = SRL (sha->buf[i-3] ^ sha->buf[i-8] ^ sha->buf[i-14] ^ sha->buf[i-16], 1);
  113. A = sha->hash[0];
  114. B = sha->hash[1];
  115. C = sha->hash[2];
  116. D = sha->hash[3];
  117. E = sha->hash[4];
  118. SHA (0, 19, ((C^D)&B)^D, 0x5a827999);
  119. SHA (20, 39, B^C^D, 0x6ed9eba1);
  120. SHA (40, 59, (B&C)|(D&(B|C)), 0x8f1bbcdc);
  121. SHA (60, 79, B^C^D, 0xca62c1d6);
  122. sha->hash[0] += A;
  123. sha->hash[1] += B;
  124. sha->hash[2] += C;
  125. sha->hash[3] += D;
  126. sha->hash[4] += E;
  127. }