feat: md5

This commit is contained in:
lohhiiccc 2026-04-30 15:19:17 +02:00
parent d08103532b
commit f13bdb240d
6 changed files with 210 additions and 8 deletions

8
include/md5_internal.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef MD5_INTERNAL_H
#define MD5_INTERNAL_H
#include "md5.h"
void md5_compress(struct md5_ctx *ctx, const uint8_t block[64]);
#endif

View file

@ -3,6 +3,7 @@ lib_LTLIBRARIES = libft_ssl.la
libft_ssl_la_SOURCES = libft_ssl.c \
md5/md5.c \
md5/md5_init.c \
md5/md5_compress.c \
md5/md5_update.c \
md5/md5_final.c \
sha256/sha256_init.c \

124
src/md5/md5_compress.c Normal file
View file

@ -0,0 +1,124 @@
#include "md5_internal.h"
#include <stdint.h>
/* Forward declrations */
typedef uint32_t (*md5_round_fn)(uint32_t, uint32_t, uint32_t);
typedef uint32_t (*md5_k_fn)(uint8_t);
static uint32_t md5_f(uint32_t b, uint32_t c, uint32_t d);
static uint32_t md5_g(uint32_t b, uint32_t c, uint32_t d);
static uint32_t md5_h(uint32_t b, uint32_t c, uint32_t d);
static uint32_t md5_i(uint32_t b, uint32_t c, uint32_t d);
static uint32_t md5_k0(uint8_t i);
static uint32_t md5_k1(uint8_t i);
static uint32_t md5_k2(uint8_t i);
static uint32_t md5_k3(uint8_t i);
static uint32_t md5_leftrotate(uint32_t x, uint32_t n);
static void md5_decode(const uint8_t block[64], uint32_t m[16]);
/* ------------------- */
static const md5_round_fn round_fns[4] = { md5_f, md5_g, md5_h, md5_i };
static const md5_k_fn round_k[4] = { md5_k0, md5_k1, md5_k2, md5_k3 };
void
md5_compress(struct md5_ctx *ctx, const uint8_t block[64])
{
uint32_t m[16];
uint32_t a, b, c, d;
uint32_t temp;
md5_decode(block, m);
a = ctx->state[0];
b = ctx->state[1];
c = ctx->state[2];
d = ctx->state[3];
for (uint8_t i = 0; i < 64; ++i)
{
const uint8_t idx = (i / 16) & 3;
const uint32_t k = round_k[idx](i);
temp = a + round_fns[idx](b, c, d) + m[k] + g_md5_T[i];
temp = md5_leftrotate(temp, g_md5_s[i]) + b;
a = d; d = c; c = b; b = temp;
}
ctx->state[0] += a;
ctx->state[1] += b;
ctx->state[2] += c;
ctx->state[3] += d;
}
/* Decode 64 bytes into 16 x uint32_t words (little-endian) */
static void
md5_decode(const uint8_t block[64], uint32_t m[16])
{
for (uint8_t i = 0; i < 16; ++i)
{
const uint8_t i4 = i * 4;
m[i] = (uint32_t)block[i4 + 0] << 0
| (uint32_t)block[i4 + 1] << 8
| (uint32_t)block[i4 + 2] << 16
| (uint32_t)block[i4 + 3] << 24;
}
}
/* Round functions */
static uint32_t
md5_f(uint32_t b, uint32_t c, uint32_t d)
{
return (b & c) | (~b & d);
}
static uint32_t
md5_g(uint32_t b, uint32_t c, uint32_t d)
{
return (b & d) | (c & ~d);
}
static uint32_t
md5_h(uint32_t b, uint32_t c, uint32_t d)
{
return b ^ c ^ d;
}
static uint32_t
md5_i(uint32_t b, uint32_t c, uint32_t d)
{
return c ^ (b | ~d);
}
/* k selectors */
static uint32_t
md5_k0(uint8_t i)
{
return (uint32_t)i;
}
static uint32_t
md5_k1(uint8_t i)
{
return (uint32_t)((1 + 5 * i) & 15);
}
static uint32_t
md5_k2(uint8_t i)
{
return (uint32_t)((5 + 3 * i) & 15);
}
static uint32_t
md5_k3(uint8_t i)
{
return (uint32_t)((7 * i) & 15);
}
static uint32_t
md5_leftrotate(uint32_t x, uint32_t n)
{
return (x << n) | (x >> (32u - n));
}

View file

@ -1,6 +1,56 @@
#include "compiler.h"
#include "md5.h"
#include "md5_internal.h"
#include <stdint.h>
void md5_final(__unused void *ctx, __unused uint8_t *out)
/* Forward declarations */
static void md5_pad(struct md5_ctx *ctx);
static inline void md5_write_len(struct md5_ctx *ctx, uint64_t bitlen);
static void md5_encode(const struct md5_ctx *ctx, uint8_t out[16]);
/* ---------------- */
void md5_final(void *ctx, uint8_t *out)
{
struct md5_ctx *local_ctx = ctx;
md5_pad(local_ctx);
md5_encode(local_ctx, out);
}
static void
md5_pad(struct md5_ctx *ctx)
{
uint64_t bitlen = ctx->count * 8;
ctx->buf[ctx->count++ & 63] = 0x80;
if ((ctx->count & 63) > 56)
{
while ((ctx->count & 63) != 0)
ctx->buf[ctx->count++ & 63] = 0x00;
md5_compress(ctx, ctx->buf);
}
while ((ctx->count & 63) < 56)
ctx->buf[ctx->count++ & 63] = 0x00;
md5_write_len(ctx, bitlen);
md5_compress(ctx, ctx->buf);
}
static inline void
md5_write_len(struct md5_ctx *ctx, uint64_t bitlen)
{
for (uint8_t i = 0; i < 8; ++i)
ctx->buf[56 + i] = (uint8_t)(bitlen >> (8 * i));
}
static void
md5_encode(const struct md5_ctx *ctx, uint8_t out[16])
{
for (uint8_t i = 0; i < 4; ++i)
{
const uint8_t i4 = i * 4;
uint32_t v = ctx->state[i];
out[i4 + 0] = (uint8_t)(v >> 0);
out[i4 + 1] = (uint8_t)(v >> 8);
out[i4 + 2] = (uint8_t)(v >> 16);
out[i4 + 3] = (uint8_t)(v >> 24);
}
}

View file

@ -1,6 +1,13 @@
#include "compiler.h"
#include "md5.h"
void md5_init(__unused void *ctx)
void md5_init(void *ctx)
{
struct md5_ctx *local_ctx = ctx;
local_ctx->state[0] = 0x67452301;
local_ctx->state[1] = 0xEFCDAB89;
local_ctx->state[2] = 0x98BADCFE;
local_ctx->state[3] = 0x10325476;
local_ctx->count = 0;
}

View file

@ -1,7 +1,19 @@
#include "compiler.h"
#include "md5.h"
#include "md5_internal.h"
#include <stddef.h>
#include <stdint.h>
void md5_update(__unused void *ctx, __unused const uint8_t *data,
__unused size_t len)
void md5_update(void *ctx, const uint8_t *data, size_t len)
{
struct md5_ctx *local_ctx = ctx;
for (size_t i = 0; i < len; ++i)
{
local_ctx->buf[(local_ctx->count & 63)] = data[i];
++local_ctx->count;
if (0 == (local_ctx->count & 63))
md5_compress(local_ctx, local_ctx->buf);
}
}