/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* sl_md5.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: bchanot +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2018/09/24 00:10:37 by bchanot #+# #+# */ /* Updated: 2018/10/10 12:53:46 by bchanot ### ########.fr */ /* */ /* ************************************************************************** */ #include "ft_ssl.h" #include "sl_md5.h" static const t_uint32 g_k[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 }; static const t_uint32 g_r[64] = { 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, \ 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, \ 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, \ 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 }; static void sl_md5_get_registers(t_process_md5 *t, size_t cpt, t_uint32 bytes[2]) { if (cpt < 16) { bytes[0] = (t->b & t->c) | ((~t->b) & t->d); bytes[1] = cpt; } else if (cpt < 32) { bytes[0] = (t->d & t->b) | ((~t->d) & t->c); bytes[1] = (5 * cpt + 1) % 16; } else if (cpt < 48) { bytes[0] = t->b ^ t->c ^ t->d; bytes[1] = (3 * cpt + 5) % 16; } else { bytes[0] = t->c ^ (t->b | (~t->d)); bytes[1] = (7 * cpt) % 16; } } static void sl_md5_process(t_md5 *ctx, t_uint32 *data) { t_process_md5 t; t_uint32 bytes[2]; size_t cpt; t.a = ctx->state[0]; t.b = ctx->state[1]; t.c = ctx->state[2]; t.d = ctx->state[3]; cpt = -1; while (++cpt < 64) { sl_md5_get_registers(&t, cpt, bytes); bytes[0] = bytes[0] + t.a + g_k[cpt] + data[bytes[1]]; t.a = t.d; t.d = t.c; t.c = t.b; t.b = t.b + ROL32(bytes[0], g_r[cpt]); } ctx->state[0] += t.a; ctx->state[1] += t.b; ctx->state[2] += t.c; ctx->state[3] += t.d; } void sl_md5_update(t_md5 *ctx, const t_uint8 *data, size_t len) { t_uint32 avail; avail = sizeof(ctx->buff) - (ctx->count & 0x3f); ctx->count += len; if (avail > len) { ft_memcpy((char *)ctx->buff + (sizeof(ctx->buff) - avail), data, len); return ; } ft_memcpy((char *)ctx->buff + (sizeof(ctx->buff) - avail), data, avail); sl_md5_process(ctx, ctx->buff); data += avail; len -= avail; while (len >= sizeof(ctx->buff)) { ft_memcpy(ctx->buff, data, sizeof(ctx->buff)); sl_md5_process(ctx, ctx->buff); data += sizeof(ctx->buff); len -= sizeof(ctx->buff); } ft_memcpy(ctx->buff, data, len); } void sl_md5_final(t_md5 *ctx, t_uint8 *hash) { size_t offset; char *padding; int pad_len; offset = ctx->count & 0x3f; padding = (char *)ctx->buff + offset; pad_len = 56 - (offset + 1); *padding = 0x80; padding++; if (pad_len < 0) { ft_bzero(padding, pad_len + 8); sl_md5_process(ctx, ctx->buff); padding = (char *)ctx->buff; pad_len = 56; } ft_bzero(padding, pad_len); ctx->buff[14] = ctx->count << 3; ctx->buff[15] = ctx->count >> 29; sl_md5_process(ctx, ctx->buff); ft_memcpy(hash, ctx->state, sizeof(ctx->state)); } void sl_md5_init(t_md5 *ctx) { ctx->state[0] = 0x67452301; ctx->state[1] = 0xefcdab89; ctx->state[2] = 0x98badcfe; ctx->state[3] = 0x10325476; ctx->count = 0; }