Day: June 8, 2013

Public Domain MD5 C Source code

In this article I will present complete code for performing a MD5 hash of a string provided on a command line. For the Proof of Work project I need an MD5 hash library. I could use any hash, but chose to use MD5 for its simplicity and speed.

Full source code and Windows x64 and OSX x64 binaries are provided: Md5String.zip

The MD5 code is in a file called LibMd5.c, and it along with its header LibMd5.h contain all the code required to perform MD5 hash calculations. There are three functions. The header file is as follows, and describes the operation.

//////////////////////////////////////////////////////////////////////////////////
//  LibMd5
//  
//  Implementation of MD5 hash function. Originally written by Alexander Peslyak.
//  Modified by WaterJuice retaining 
//  Public Domain license.
//  
//  License: Entered into the Public Domain by WaterJuice - June 2013
//////////////////////////////////////////////////////////////////////////////////

#ifndef _LibMd5_h_
#define _LibMd5_h_

//////////////////////////////////////////////////////////////////////////////////
//  IMPORTS
//////////////////////////////////////////////////////////////////////////////////

#include <stdint.h>
#include <stdio.h>

//////////////////////////////////////////////////////////////////////////////////
//  TYPES
//////////////////////////////////////////////////////////////////////////////////

// Md5Context - This must be initialised using Md5Initialised. Do not modify the 
// contents of this structure directly.
typedef struct 
{
    uint32_t     lo;
    uint32_t     hi;
    uint32_t     a;
    uint32_t     b;
    uint32_t     c;
    uint32_t     d;
    uint8_t      buffer[64];
    uint32_t     block[16];
} Md5Context;

#define MD5_HASH_SIZE           ( 128 / 8 )

typedef struct
{
    uint8_t      bytes [MD5_HASH_SIZE];
} MD5_HASH;

//////////////////////////////////////////////////////////////////////////////////
//  PUBLIC FUNCTIONS
//////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////
//  Md5Initialise
//  
//  Initialises an MD5 Context. Use this to initialise/reset a context.
//////////////////////////////////////////////////////////////////////////////////
void 
    Md5Initialise
    (
        Md5Context*     Context
    );

//////////////////////////////////////////////////////////////////////////////////
//  Md5Update
//
//  Adds data to the MD5 context. This will process the data and update the 
//  internal state of the context. Keep on calling this function until all the
//  data has been added. Then call Md5Finalise to calculate the 
//////////////////////////////////////////////////////////////////////////////////
void 
    Md5Update
    (
        Md5Context*         Context,
        void*               Buffer, 
        size_t              BufferSize
    );

//////////////////////////////////////////////////////////////////////////////////
//  Md5Finalise
//
//  Performs the final calculation of the hash and returns the digest (16 byte 
//  buffer containing 128bit hash). After calling this, Md5Initialised must be 
//  used to reuse the context.
//////////////////////////////////////////////////////////////////////////////////
void 
    Md5Finalise
    (
        Md5Context*         Context,
        MD5_HASH*           Digest
    );

//////////////////////////////////////////////////////////////////////////////////
#endif //_LibMd5_h_

Md5String

The project Md5String is a simple command line program that takes a string on the command line and calculates the MD5 hash and prints it out in hex. This demonstrates how to use LibMd5

int
    main
    (
        int             ArgC,
        char**          ArgV
    )
{
    char*           string;
    Md5Context      md5Context;
    MD5_HASH        md5Hash;
    uint16_t        i;

    if( 2 != ArgC )
    {
        printf( 
            "Syntax\n"
            "   Md5String \n" );
        return 1;
    }

    string = ArgV[1];

    Md5Initialise( &md5Context );
    Md5Update( &md5Context, string, strlen(string) );
    Md5Finalise( &md5Context, &md5Hash );

    for( i=0; i<sizeof(md5Hash); i++ )
    {
        printf( "%2.2x", md5Hash.bytes[i] );
    }
    printf( "\n" );

    return 0;
}

I have compiled a Windows x64 binary and an OSX x64 binary which I am including with the source code. Note to provide a string with spaces you need to surround the string with quotes.

At the end of this article is the link to the source code and binaries.

Testing MD5

When using any cryptographic functions it is important to test them so you can be confident they actaully work. I have a test project that tests the MD5 hashes against a set of known test vectors. I have not provided it here though as that would not be sufficient to provide assurance. I may have put the wrong hashes into the test code, so how would you know they are actaully correct. So instead you should test it yourself. You can use Md5String itself to test it (as long as its just ascii strings you provide).

There are various sources of test vectors. NIST provide a small set of informal MD5 test vectors at http://www.nsrl.nist.gov/testdata/. RFC1321 is the official description of MD5 and contains some test vectors at the end. These can be found at http://tools.ietf.org/html/rfc1321

Download

Md5String.zip – This contains the source code of Md5String. This can be compiled as is with Visual Studio 2010, and Xcode 4.6. Additionally a precompiled x64 binaries are included for both platforms. Note The Windows executable is compiled for Windows Vista and above, while the OSX ones is compiled for Lion (10.7) and above.

License

All source code presented in WaterJuice is public domain. Either written by myself, or taken from other public domain sources. I dislike the numerous licenses that are attached to most open source projects. I could sum up the license I wish in one simple sentence “This is public domain, do what ever you want with it, don’t blame me”. Unforunately the world is run by lawyers and lawsuits, so to avoid any complications I release this to public domain using the “unlicense” legalise

This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.

In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to http://unlicense.org/

 

Advertisement