md5.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #include "os.h"
  2. #include <libsec.h>
  3. /*
  4. * rfc1321 requires that I include this. The code is new. The constants
  5. * all come from the rfc (hence the copyright). We trade a table for the
  6. * macros in rfc. The total size is a lot less. -- presotto
  7. *
  8. * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
  9. * rights reserved.
  10. *
  11. * License to copy and use this software is granted provided that it
  12. * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
  13. * Algorithm" in all material mentioning or referencing this software
  14. * or this function.
  15. *
  16. * License is also granted to make and use derivative works provided
  17. * that such works are identified as "derived from the RSA Data
  18. * Security, Inc. MD5 Message-Digest Algorithm" in all material
  19. * mentioning or referencing the derived work.
  20. *
  21. * RSA Data Security, Inc. makes no representations concerning either
  22. * the merchantability of this software or the suitability of this
  23. * software forany particular purpose. It is provided "as is"
  24. * without express or implied warranty of any kind.
  25. * These notices must be retained in any copies of any part of this
  26. * documentation and/or software.
  27. */
  28. static void encode(uchar*, u32int*, ulong);
  29. extern void _md5block(uchar*, ulong, u32int*);
  30. MD5state*
  31. md5(uchar *p, ulong len, uchar *digest, MD5state *s)
  32. {
  33. u32int x[16];
  34. uchar buf[128];
  35. int i;
  36. uchar *e;
  37. if(s == nil){
  38. s = malloc(sizeof(*s));
  39. if(s == nil)
  40. return nil;
  41. memset(s, 0, sizeof(*s));
  42. s->malloced = 1;
  43. }
  44. if(s->seeded == 0){
  45. /* seed the state, these constants would look nicer big-endian */
  46. s->state[0] = 0x67452301;
  47. s->state[1] = 0xefcdab89;
  48. s->state[2] = 0x98badcfe;
  49. s->state[3] = 0x10325476;
  50. s->seeded = 1;
  51. }
  52. /* fill out the partial 64 byte block from previous calls */
  53. if(s->blen){
  54. i = 64 - s->blen;
  55. if(len < i)
  56. i = len;
  57. memmove(s->buf + s->blen, p, i);
  58. len -= i;
  59. s->blen += i;
  60. p += i;
  61. if(s->blen == 64){
  62. _md5block(s->buf, s->blen, s->state);
  63. s->len += s->blen;
  64. s->blen = 0;
  65. }
  66. }
  67. /* do 64 byte blocks */
  68. i = len & ~0x3f;
  69. if(i){
  70. _md5block(p, i, s->state);
  71. s->len += i;
  72. len -= i;
  73. p += i;
  74. }
  75. /* save the left overs if not last call */
  76. if(digest == 0){
  77. if(len){
  78. memmove(s->buf, p, len);
  79. s->blen += len;
  80. }
  81. return s;
  82. }
  83. /*
  84. * this is the last time through, pad what's left with 0x80,
  85. * 0's, and the input count to create a multiple of 64 bytes
  86. */
  87. if(s->blen){
  88. p = s->buf;
  89. len = s->blen;
  90. } else {
  91. memmove(buf, p, len);
  92. p = buf;
  93. }
  94. s->len += len;
  95. e = p + len;
  96. if(len < 56)
  97. i = 56 - len;
  98. else
  99. i = 120 - len;
  100. memset(e, 0, i);
  101. *e = 0x80;
  102. len += i;
  103. /* append the count */
  104. x[0] = s->len<<3;
  105. x[1] = s->len>>29;
  106. encode(p+len, x, 8);
  107. /* digest the last part */
  108. _md5block(p, len+8, s->state);
  109. s->len += len;
  110. /* return result and free state */
  111. encode(digest, s->state, MD5dlen);
  112. if(s->malloced == 1)
  113. free(s);
  114. return nil;
  115. }
  116. /*
  117. * encodes input (u32int) into output (uchar). Assumes len is
  118. * a multiple of 4.
  119. */
  120. static void
  121. encode(uchar *output, u32int *input, ulong len)
  122. {
  123. u32int x;
  124. uchar *e;
  125. for(e = output + len; output < e;) {
  126. x = *input++;
  127. *output++ = x;
  128. *output++ = x >> 8;
  129. *output++ = x >> 16;
  130. *output++ = x >> 24;
  131. }
  132. }