md5.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the License); you may
  5. * not use this file except in compliance with the License.
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. */
  9. #include <string.h>
  10. #include <gmssl/md5.h>
  11. #include <gmssl/endian.h>
  12. #define F(B, C, D) (((B) & (C)) | ((~(B)) & (D)))
  13. #define G(B, C, D) (((B) & (D)) | ((C) & (~(D))))
  14. #define H(B, C, D) ((B) ^ (C) ^ (D))
  15. #define I(B, C, D) ((C) ^ ((B) | (~(D))))
  16. static const uint32_t K[] = {
  17. 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
  18. 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
  19. 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
  20. 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
  21. 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
  22. 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
  23. 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
  24. 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
  25. 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
  26. 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
  27. 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
  28. 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
  29. 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
  30. 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
  31. 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
  32. 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
  33. };
  34. static const int S[] = {
  35. 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
  36. 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
  37. 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
  38. 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21,
  39. };
  40. static void md5_compress_blocks(uint32_t state[4],
  41. const unsigned char *data, size_t blocks)
  42. {
  43. uint32_t A;
  44. uint32_t B;
  45. uint32_t C;
  46. uint32_t D;
  47. uint32_t T;
  48. uint32_t W[16];
  49. int g, i;
  50. while (blocks--) {
  51. A = state[0];
  52. B = state[1];
  53. C = state[2];
  54. D = state[3];
  55. for (i = 0; i < 16; i++) {
  56. W[i] = GETU32_LE(data);
  57. data += sizeof(uint32_t);
  58. }
  59. for (i = 0; i < 16; i++) {
  60. T = ROL32(A + F(B, C, D) + W[i] + K[i], S[i]) + B;
  61. A = D;
  62. D = C;
  63. C = B;
  64. B = T;
  65. }
  66. for (; i < 32; i++) {
  67. g = (5 * i + 1) % 16;
  68. T = ROL32(A + G(B, C, D) + W[g] + K[i], S[i]) + B;
  69. A = D;
  70. D = C;
  71. C = B;
  72. B = T;
  73. }
  74. for (; i < 48; i++) {
  75. g = (3 * i + 5) % 16;
  76. T = ROL32(A + H(B, C, D) + W[g] + K[i], S[i]) + B;
  77. A = D;
  78. D = C;
  79. C = B;
  80. B = T;
  81. }
  82. for (; i < 64; i++) {
  83. g = (7 * i) % 16;
  84. T = ROL32(A + I(B, C, D) + W[g] + K[i], S[i]) + B;
  85. A = D;
  86. D = C;
  87. C = B;
  88. B = T;
  89. }
  90. state[0] += A;
  91. state[1] += B;
  92. state[2] += C;
  93. state[3] += D;
  94. }
  95. }
  96. void md5_init(MD5_CTX *ctx)
  97. {
  98. memset(ctx, 0, sizeof(*ctx));
  99. ctx->state[0] = 0x67452301;
  100. ctx->state[1] = 0xefcdab89;
  101. ctx->state[2] = 0x98badcfe;
  102. ctx->state[3] = 0x10325476;
  103. }
  104. void md5_update(MD5_CTX *ctx, const unsigned char *data, size_t datalen)
  105. {
  106. size_t blocks;
  107. ctx->num &= 0x3f;
  108. if (ctx->num) {
  109. size_t left = MD5_BLOCK_SIZE - ctx->num;
  110. if (datalen < left) {
  111. memcpy(ctx->block + ctx->num, data, datalen);
  112. ctx->num += datalen;
  113. return;
  114. } else {
  115. memcpy(ctx->block + ctx->num, data, left);
  116. md5_compress_blocks(ctx->state, ctx->block, 1);
  117. ctx->nblocks++;
  118. data += left;
  119. datalen -= left;
  120. }
  121. }
  122. blocks = datalen / MD5_BLOCK_SIZE;
  123. md5_compress_blocks(ctx->state, data, blocks);
  124. ctx->nblocks += blocks;
  125. data += MD5_BLOCK_SIZE * blocks;
  126. datalen -= MD5_BLOCK_SIZE * blocks;
  127. ctx->num = datalen;
  128. if (datalen) {
  129. memcpy(ctx->block, data, datalen);
  130. }
  131. }
  132. void md5_finish(MD5_CTX *ctx, unsigned char *dgst)
  133. {
  134. int i;
  135. ctx->num &= 0x3f;
  136. ctx->block[ctx->num] = 0x80;
  137. if (ctx->num <= MD5_BLOCK_SIZE - 9) {
  138. memset(ctx->block + ctx->num + 1, 0, MD5_BLOCK_SIZE - ctx->num - 9);
  139. } else {
  140. memset(ctx->block + ctx->num + 1, 0, MD5_BLOCK_SIZE - ctx->num - 1);
  141. md5_compress_blocks(ctx->state, ctx->block, 1);
  142. memset(ctx->block, 0, MD5_BLOCK_SIZE - 8);
  143. }
  144. PUTU64_LE(ctx->block + 56, (ctx->nblocks << 9) + (ctx->num << 3));
  145. md5_compress_blocks(ctx->state, ctx->block, 1);
  146. for (i = 0; i < 4; i++) {
  147. PUTU32_LE(dgst, ctx->state[i]);
  148. dgst += sizeof(uint32_t);
  149. }
  150. memset(ctx, 0, sizeof(*ctx));
  151. }
  152. void md5_digest(const unsigned char *data, size_t datalen,
  153. unsigned char dgst[MD5_DIGEST_SIZE])
  154. {
  155. MD5_CTX ctx;
  156. md5_init(&ctx);
  157. md5_update(&ctx, data, datalen);
  158. md5_finish(&ctx, dgst);
  159. }