* This file is part of the openHiTLS project.
*
* openHiTLS is licensed under the Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "hitls_build.h"
#ifdef HITLS_CRYPTO_MD5
#include "bsl_err_internal.h"
#include "crypt_errno.h"
#include "crypt_utils.h"
#include "md5_core.h"
#include "crypt_md5.h"
#ifdef __cplusplus
extern "C" {
#endif
#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~(z))))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~(z))))
#define FF(a, b, c, d, x, s, ac) \
do { \
(a) += F((b), (c), (d)) + (x) + (ac); \
(a) = ROTL32((a), (s)); \
(a) += (b); \
} while (0)
#define GG(a, b, c, d, x, s, ac) \
do { \
(a) += G((b), (c), (d)) + (x) + (ac); \
(a) = ROTL32((a), (s)); \
(a) += (b); \
} while (0)
#define HH(a, b, c, d, x, s, ac) \
do { \
(a) += H((b), (c), (d)) + (x) + (ac); \
(a) = ROTL32((a), (s)); \
(a) += (b); \
} while (0)
#define II(a, b, c, d, x, s, ac) \
do { \
(a) += I((b), (c), (d)) + (x) + (ac); \
(a) = ROTL32((a), (s)); \
(a) += (b); \
} while (0)
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static const uint32_t T[64] = {
0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE,
0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501,
0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE,
0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821,
0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA,
0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8,
0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED,
0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A,
0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C,
0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70,
0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05,
0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665,
0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039,
0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1,
0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1,
0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391,
};
void MD5_Compress(uint32_t state[4], const uint8_t *data, uint32_t blockCnt)
{
uint32_t w[16] = {0};
const uint8_t *input = data;
uint32_t count = blockCnt;
while (count > 0) {
w[0] = GET_UINT32_LE(input, 0);
w[1] = GET_UINT32_LE(input, 4);
w[2] = GET_UINT32_LE(input, 8);
w[3] = GET_UINT32_LE(input, 12);
w[4] = GET_UINT32_LE(input, 16);
w[5] = GET_UINT32_LE(input, 20);
w[6] = GET_UINT32_LE(input, 24);
w[7] = GET_UINT32_LE(input, 28);
w[8] = GET_UINT32_LE(input, 32);
w[9] = GET_UINT32_LE(input, 36);
w[10] = GET_UINT32_LE(input, 40);
w[11] = GET_UINT32_LE(input, 44);
w[12] = GET_UINT32_LE(input, 48);
w[13] = GET_UINT32_LE(input, 52);
w[14] = GET_UINT32_LE(input, 56);
w[15] = GET_UINT32_LE(input, 60);
uint32_t a = state[0];
uint32_t b = state[1];
uint32_t c = state[2];
uint32_t d = state[3];
FF(a, b, c, d, w[0], S11, T[0]);
FF(d, a, b, c, w[1], S12, T[1]);
FF(c, d, a, b, w[2], S13, T[2]);
FF(b, c, d, a, w[3], S14, T[3]);
FF(a, b, c, d, w[4], S11, T[4]);
FF(d, a, b, c, w[5], S12, T[5]);
FF(c, d, a, b, w[6], S13, T[6]);
FF(b, c, d, a, w[7], S14, T[7]);
FF(a, b, c, d, w[8], S11, T[8]);
FF(d, a, b, c, w[9], S12, T[9]);
FF(c, d, a, b, w[10], S13, T[10]);
FF(b, c, d, a, w[11], S14, T[11]);
FF(a, b, c, d, w[12], S11, T[12]);
FF(d, a, b, c, w[13], S12, T[13]);
FF(c, d, a, b, w[14], S13, T[14]);
FF(b, c, d, a, w[15], S14, T[15]);
GG(a, b, c, d, w[1], S21, T[16]);
GG(d, a, b, c, w[6], S22, T[17]);
GG(c, d, a, b, w[11], S23, T[18]);
GG(b, c, d, a, w[0], S24, T[19]);
GG(a, b, c, d, w[5], S21, T[20]);
GG(d, a, b, c, w[10], S22, T[21]);
GG(c, d, a, b, w[15], S23, T[22]);
GG(b, c, d, a, w[4], S24, T[23]);
GG(a, b, c, d, w[9], S21, T[24]);
GG(d, a, b, c, w[14], S22, T[25]);
GG(c, d, a, b, w[3], S23, T[26]);
GG(b, c, d, a, w[8], S24, T[27]);
GG(a, b, c, d, w[13], S21, T[28]);
GG(d, a, b, c, w[2], S22, T[29]);
GG(c, d, a, b, w[7], S23, T[30]);
GG(b, c, d, a, w[12], S24, T[31]);
HH(a, b, c, d, w[5], S31, T[32]);
HH(d, a, b, c, w[8], S32, T[33]);
HH(c, d, a, b, w[11], S33, T[34]);
HH(b, c, d, a, w[14], S34, T[35]);
HH(a, b, c, d, w[1], S31, T[36]);
HH(d, a, b, c, w[4], S32, T[37]);
HH(c, d, a, b, w[7], S33, T[38]);
HH(b, c, d, a, w[10], S34, T[39]);
HH(a, b, c, d, w[13], S31, T[40]);
HH(d, a, b, c, w[0], S32, T[41]);
HH(c, d, a, b, w[3], S33, T[42]);
HH(b, c, d, a, w[6], S34, T[43]);
HH(a, b, c, d, w[9], S31, T[44]);
HH(d, a, b, c, w[12], S32, T[45]);
HH(c, d, a, b, w[15], S33, T[46]);
HH(b, c, d, a, w[2], S34, T[47]);
II(a, b, c, d, w[0], S41, T[48]);
II(d, a, b, c, w[7], S42, T[49]);
II(c, d, a, b, w[14], S43, T[50]);
II(b, c, d, a, w[5], S44, T[51]);
II(a, b, c, d, w[12], S41, T[52]);
II(d, a, b, c, w[3], S42, T[53]);
II(c, d, a, b, w[10], S43, T[54]);
II(b, c, d, a, w[1], S44, T[55]);
II(a, b, c, d, w[8], S41, T[56]);
II(d, a, b, c, w[15], S42, T[57]);
II(c, d, a, b, w[6], S43, T[58]);
II(b, c, d, a, w[13], S44, T[59]);
II(a, b, c, d, w[4], S41, T[60]);
II(d, a, b, c, w[11], S42, T[61]);
II(c, d, a, b, w[2], S43, T[62]);
II(b, c, d, a, w[9], S44, T[63]);
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
input += CRYPT_MD5_BLOCKSIZE;
count--;
}
}
#ifdef __cplusplus
}
#endif
#endif