slidescript/src/md5.c

284 lines
12 KiB
C
Executable File

// BUSYBOX MD5 code, repurposed for the function in SlideScript
// Licensing and contributions to the BusyBox development team, changes
// and cleanup done by Bob (OldCoder) Kiraly, 2021
/*
SlideScript - minimalistic top-down scripting language.
(C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2)
View README file supplied with this software for more details
*/
#include "inc/deps.h"
#include "inc/md5.h"
#define ZERO 0
#define ONE 1
#define TWO 2
#define FALSE 0
#define TRUE 1
static inline uint32_md5 rotl32 (uint32_md5 x, unsigned n)
{
return (x << n) | (x >> (32 - n));
}
static inline uint32_md5 rotr32 (uint32_md5 x, unsigned n)
{
return (x >> n) | (x << (32 - n));
}
static inline uint64_md5 rotr64 (uint64_md5 x, unsigned n)
{
return (x >> n) | (x << (64 - n));
}
static inline uint64_md5 rotl64(uint64_md5 x, unsigned n)
{
return (x << n) | (x >> (64 - n));
}
static void common64_hash
(md5_ctx_t *ctx, const void *buffer, size_t len)
{
unsigned bufpos = ctx->total64 & 63;
ctx->total64 += len;
while (TRUE)
{
unsigned remaining = 64 - bufpos;
if (remaining > len) remaining = len;
memcpy (ctx->wbuffer + bufpos, buffer, remaining);
len -= remaining;
buffer = (const char *) buffer + remaining;
bufpos += remaining;
bufpos -= 64;
if (bufpos != ZERO) break;
ctx->process_block (ctx);
}
}
static void common64_end (md5_ctx_t *ctx, int swap_needed)
{
unsigned bufpos = ctx->total64 & 63;
ctx->wbuffer [bufpos++] = 0x80;
while (1)
{
unsigned remaining = 64 - bufpos;
memset (ctx->wbuffer + bufpos, ZERO, remaining);
if (remaining >= 8)
{
uint64_md5 t = ctx->total64 << 3;
if (swap_needed) t = bswap_64 (t);
*(uint64_md5 *) (&ctx->wbuffer [64 - 8]) = t;
}
ctx->process_block (ctx);
if (remaining >= 8) break;
bufpos = ZERO;
}
}
static void md5_process_block64 (md5_ctx_t *ctx)
{
uint32_md5 *words = (void*) ctx->wbuffer;
uint32_md5 A = ctx->hash [0];
uint32_md5 B = ctx->hash [1];
uint32_md5 C = ctx->hash [2];
uint32_md5 D = ctx->hash [3];
do { A += (D ^ (B & (C ^ D))) + (*words) + 0xd76aa478; words++; A = rotl32 (A, 7); A += B; } while (0);
do { D += (C ^ (A & (B ^ C))) + (*words) + 0xe8c7b756; words++; D = rotl32 (D, 12); D += A; } while (0);
do { C += (B ^ (D & (A ^ B))) + (*words) + 0x242070db; words++; C = rotl32 (C, 17); C += D; } while (0);
do { B += (A ^ (C & (D ^ A))) + (*words) + 0xc1bdceee; words++; B = rotl32 (B, 22); B += C; } while (0);
do { A += (D ^ (B & (C ^ D))) + (*words) + 0xf57c0faf; words++; A = rotl32 (A, 7); A += B; } while (0);
do { D += (C ^ (A & (B ^ C))) + (*words) + 0x4787c62a; words++; D = rotl32 (D, 12); D += A; } while (0);
do { C += (B ^ (D & (A ^ B))) + (*words) + 0xa8304613; words++; C = rotl32 (C, 17); C += D; } while (0);
do { B += (A ^ (C & (D ^ A))) + (*words) + 0xfd469501; words++; B = rotl32 (B, 22); B += C; } while (0);
do { A += (D ^ (B & (C ^ D))) + (*words) + 0x698098d8; words++; A = rotl32 (A, 7); A += B; } while (0);
do { D += (C ^ (A & (B ^ C))) + (*words) + 0x8b44f7af; words++; D = rotl32 (D, 12); D += A; } while (0);
do { C += (B ^ (D & (A ^ B))) + (*words) + 0xffff5bb1; words++; C = rotl32 (C, 17); C += D; } while (0);
do { B += (A ^ (C & (D ^ A))) + (*words) + 0x895cd7be; words++; B = rotl32 (B, 22); B += C; } while (0);
do { A += (D ^ (B & (C ^ D))) + (*words) + 0x6b901122; words++; A = rotl32 (A, 7); A += B; } while (0);
do { D += (C ^ (A & (B ^ C))) + (*words) + 0xfd987193; words++; D = rotl32 (D, 12); D += A; } while (0);
do { C += (B ^ (D & (A ^ B))) + (*words) + 0xa679438e; words++; C = rotl32 (C, 17); C += D; } while (0);
do { B += (A ^ (C & (D ^ A))) + (*words) + 0x49b40821; words++; B = rotl32 (B, 22); B += C; } while (0);
words -= 16;
do { A += (C ^ (D & (B ^ C))) + words [ 1] + 0xf61e2562; A = rotl32 (A, 5); A += B; } while (0);
do { D += (B ^ (C & (A ^ B))) + words [ 6] + 0xc040b340; D = rotl32 (D, 9); D += A; } while (0);
do { C += (A ^ (B & (D ^ A))) + words [11] + 0x265e5a51; C = rotl32 (C, 14); C += D; } while (0);
do { B += (D ^ (A & (C ^ D))) + words [ 0] + 0xe9b6c7aa; B = rotl32 (B, 20); B += C; } while (0);
do { A += (C ^ (D & (B ^ C))) + words [ 5] + 0xd62f105d; A = rotl32 (A, 5); A += B; } while (0);
do { D += (B ^ (C & (A ^ B))) + words [10] + 0x02441453; D = rotl32 (D, 9); D += A; } while (0);
do { C += (A ^ (B & (D ^ A))) + words [15] + 0xd8a1e681; C = rotl32 (C, 14); C += D; } while (0);
do { B += (D ^ (A & (C ^ D))) + words [ 4] + 0xe7d3fbc8; B = rotl32 (B, 20); B += C; } while (0);
do { A += (C ^ (D & (B ^ C))) + words [ 9] + 0x21e1cde6; A = rotl32 (A, 5); A += B; } while (0);
do { D += (B ^ (C & (A ^ B))) + words [14] + 0xc33707d6; D = rotl32 (D, 9); D += A; } while (0);
do { C += (A ^ (B & (D ^ A))) + words [ 3] + 0xf4d50d87; C = rotl32 (C, 14); C += D; } while (0);
do { B += (D ^ (A & (C ^ D))) + words [ 8] + 0x455a14ed; B = rotl32 (B, 20); B += C; } while (0);
do { A += (C ^ (D & (B ^ C))) + words [13] + 0xa9e3e905; A = rotl32 (A, 5); A += B; } while (0);
do { D += (B ^ (C & (A ^ B))) + words [ 2] + 0xfcefa3f8; D = rotl32 (D, 9); D += A; } while (0);
do { C += (A ^ (B & (D ^ A))) + words [ 7] + 0x676f02d9; C = rotl32 (C, 14); C += D; } while (0);
do { B += (D ^ (A & (C ^ D))) + words [12] + 0x8d2a4c8a; B = rotl32 (B, 20); B += C; } while (0);
do { A += (B ^ C ^ D) + words [ 5] + 0xfffa3942; A = rotl32 (A, 4); A += B; } while (0);
do { D += (A ^ B ^ C) + words [ 8] + 0x8771f681; D = rotl32 (D, 11); D += A; } while (0);
do { C += (D ^ A ^ B) + words [11] + 0x6d9d6122; C = rotl32 (C, 16); C += D; } while (0);
do { B += (C ^ D ^ A) + words [14] + 0xfde5380c; B = rotl32 (B, 23); B += C; } while (0);
do { A += (B ^ C ^ D) + words [ 1] + 0xa4beea44; A = rotl32 (A, 4); A += B; } while (0);
do { D += (A ^ B ^ C) + words [ 4] + 0x4bdecfa9; D = rotl32 (D, 11); D += A; } while (0);
do { C += (D ^ A ^ B) + words [ 7] + 0xf6bb4b60; C = rotl32 (C, 16); C += D; } while (0);
do { B += (C ^ D ^ A) + words [10] + 0xbebfbc70; B = rotl32 (B, 23); B += C; } while (0);
do { A += (B ^ C ^ D) + words [13] + 0x289b7ec6; A = rotl32 (A, 4); A += B; } while (0);
do { D += (A ^ B ^ C) + words [ 0] + 0xeaa127fa; D = rotl32 (D, 11); D += A; } while (0);
do { C += (D ^ A ^ B) + words [ 3] + 0xd4ef3085; C = rotl32 (C, 16); C += D; } while (0);
do { B += (C ^ D ^ A) + words [ 6] + 0x04881d05; B = rotl32 (B, 23); B += C; } while (0);
do { A += (B ^ C ^ D) + words [ 9] + 0xd9d4d039; A = rotl32 (A, 4); A += B; } while (0);
do { D += (A ^ B ^ C) + words [12] + 0xe6db99e5; D = rotl32 (D, 11); D += A; } while (0);
do { C += (D ^ A ^ B) + words [15] + 0x1fa27cf8; C = rotl32 (C, 16); C += D; } while (0);
do { B += (C ^ D ^ A) + words [ 2] + 0xc4ac5665; B = rotl32 (B, 23); B += C; } while (0);
do { A += (C ^ (B | ~D)) + words [ 0] + 0xf4292244; A = rotl32 (A, 6); A += B; } while (0);
do { D += (B ^ (A | ~C)) + words [ 7] + 0x432aff97; D = rotl32 (D, 10); D += A; } while (0);
do { C += (A ^ (D | ~B)) + words [14] + 0xab9423a7; C = rotl32 (C, 15); C += D; } while (0);
do { B += (D ^ (C | ~A)) + words [ 5] + 0xfc93a039; B = rotl32 (B, 21); B += C; } while (0);
do { A += (C ^ (B | ~D)) + words [12] + 0x655b59c3; A = rotl32 (A, 6); A += B; } while (0);
do { D += (B ^ (A | ~C)) + words [ 3] + 0x8f0ccc92; D = rotl32 (D, 10); D += A; } while (0);
do { C += (A ^ (D | ~B)) + words [10] + 0xffeff47d; C = rotl32 (C, 15); C += D; } while (0);
do { B += (D ^ (C | ~A)) + words [ 1] + 0x85845dd1; B = rotl32 (B, 21); B += C; } while (0);
do { A += (C ^ (B | ~D)) + words [ 8] + 0x6fa87e4f; A = rotl32 (A, 6); A += B; } while (0);
do { D += (B ^ (A | ~C)) + words [15] + 0xfe2ce6e0; D = rotl32 (D, 10); D += A; } while (0);
do { C += (A ^ (D | ~B)) + words [ 6] + 0xa3014314; C = rotl32 (C, 15); C += D; } while (0);
do { B += (D ^ (C | ~A)) + words [13] + 0x4e0811a1; B = rotl32 (B, 21); B += C; } while (0);
do { A += (C ^ (B | ~D)) + words [ 4] + 0xf7537e82; A = rotl32 (A, 6); A += B; } while (0);
do { D += (B ^ (A | ~C)) + words [11] + 0xbd3af235; D = rotl32 (D, 10); D += A; } while (0);
do { C += (A ^ (D | ~B)) + words [ 2] + 0x2ad7d2bb; C = rotl32 (C, 15); C += D; } while (0);
do { B += (D ^ (C | ~A)) + words [ 9] + 0xeb86d391; B = rotl32 (B, 21); B += C; } while (0);
ctx->hash [0] += A;
ctx->hash [1] += B;
ctx->hash [2] += C;
ctx->hash [3] += D;
}
void md5_begin (md5_ctx_t *ctx)
{
if ((sizeof (uint8_md5 ) != 1) ||
(sizeof (uint16_md5) != 2) ||
(sizeof (uint32_md5) != 4) ||
(sizeof (uint64_md5) != 8))
{
fprintf (stderr, "%s\n",
"Internal error: Host arch not supported");
exit (ONE);
}
ctx->hash [0] = 0x67452301;
ctx->hash [1] = 0xefcdab89;
ctx->hash [2] = 0x98badcfe;
ctx->hash [3] = 0x10325476;
ctx->total64 = ZERO;
ctx->process_block = md5_process_block64;
}
void md5_hash (md5_ctx_t *ctx, const void *buffer, size_t len)
{
common64_hash (ctx, buffer, len);
}
unsigned int md5_end (md5_ctx_t *ctx, void *resbuf)
{
common64_end (ctx, ZERO);
memcpy (resbuf, ctx->hash, sizeof (ctx->hash [ZERO]) * 4);
return sizeof (ctx->hash [ZERO]) * 4;
}
char *md5_data (char *data, int len)
{
md5_ctx_t ctx; // MD5 context
int ii; // Counter
// MD5 digest - 16 raw bytes
unsigned char digest_raw [16];
// MD5 digest - 32-char string plus a
// null terminator
static unsigned char digest_hex [33];
md5_begin (&ctx);
md5_hash (&ctx, data, len);
md5_end (&ctx, digest_raw);
for (ii = ZERO; ii < 16; ii++)
{
sprintf ((char *)digest_hex + (ii * 2), "%02x", digest_raw [ii]);
}
return (char *) digest_hex;
}
#define MD5_FILE_BSIZE 8192
char *md5_file (char *ifname)
{
md5_ctx_t ctx; // MD5 context
FILE *ifp; // Input-file pointer
int ii; // Counter
int nb; // Number of bytes read
char data [MD5_FILE_BSIZE]; // Block buffer
// MD5 digest - 16 raw bytes
unsigned char digest_raw [16];
// MD5 digest - 32-char string plus a
// null terminator
static unsigned char digest_hex [33];
//--------------------------------------------------------------------
md5_begin (&ctx);
if ((ifp = fopen (ifname, "rb")) == NULL) return NULL;
while ((nb = fread (data, ONE, MD5_FILE_BSIZE, ifp)) != ZERO)
{ md5_hash (&ctx, data, nb); }
fclose (ifp);
md5_end (&ctx, digest_raw);
for (ii = ZERO; ii < 16; ii++)
{
sprintf ((char *) digest_hex + (ii * 2), "%02x", digest_raw [ii]);
}
return (char *) digest_hex;
}
char *md5_string (char *str)
{
return md5_data (str, strlen (str));
}
#ifdef TESTPROG
void main (int argc, char **argv)
{
char *ifname; // Input-file name
char *input; // Pointer to input data
int ii; // Counter
if (argc != TWO)
{
puts ("Usage: busymd5 input-file-name");
exit (ONE);
}
ifname = argv [ONE];
printf ("%s *%s\n", md5_file (ifname), ifname);
}
#endif // Endif TESTPROG