XMosh - Modular Cryptographic Digestion Tool (v0.1.x)

Written by Drew Buckley

Overview

XMosh is modular hashing tool which can have its functionality easily expanded with new modules. It can be used as a compact command-line tool, a C library and a C++ object. Further more, it is open source, so anyone can create modules and modify XMosh to infinite ends.

XMosh Command-line Tool

The XMosh tool is a simple to use command-line tool for digesting input into a cryptographic hash. This is the section that end users need only concern themselves with. XMosh can source its input from files, standard input, passed strings and from nothing at all (empty strings).

The command format for Xmosh goes as follows:
>> xmosh [SWITCHES] [MODULE_FLAG: -m] [MODULE_NAME] [FUNCTION] [CONTEXTUAL_DATA]

An example of a some calls would look like the following:
>> xmosh -m sha1.dll -f file.bin
>> echo This data will be piped into xmosh | xmosh -m sha256.dll -i
>> xmosh -m md5.dll -s "This string will be digested excluding the termination zero!"

xmosh.h

Overview

The C header xmosh.h is the only header file needed for both developing modules and incorporating XMosh in C/C++ programs. This file includes a number of preprocessor conditions and various applications of this header must be have certain symbols declared.

C/C++ programs

For use in C/C++ programs the symbol XMOSH_PRIME must be defined. This symbol will include all function prototypes for using the XMosh functionality. There are no function bodies within XMosh.h so either xmosh core library, xmosh static library or the XMosh source code must be linked to at compile-time or run-time when appropriate.

C++ requires no other special configuration, and C++ code can leverage the XMosh object which is declared and defined in xmosh.h. Two other classes are present in xmosh.h as well, the XMoshFactory class, which handles creating a XMosh from a specified external module, and the XMoshException which is thrown by XMosh functions.

Modules

When developing a module, the XMOSH_MODULE symbol must be defined and the appropriate functions must be implemented.

Platform support

Currently, xmosh.h only supports Windows and Linux x86 builds.

The Universal Types

Primitives

xmosh_byte 8-bit unsigned integer
xmosh_word16 32-bit unsigned integer
xmosh_word32 32-bit unsigned integer
xmosh_word64 64-bit unsigned integer

XMoshDigest

This structure contains a message digest represented as an array of bytes as well as a 32-bit integer informing how long many of the bytes are actually relevant. It has a max length of 512-bits.
Definition:

typedef struct
{
    xmosh_byte data[ XMOSH_DIGEST_SUM_MAX ];
    size_t length;
} XMoshDigest, XMoshSum;

data field: holds the actual sum data.
length field: represents how much of the data field is actually relevant.

XMoshContext

This structure contains the context of the current digestion. Unless you are developing a module, then you will never need to any of this structure's fields directly. A reference to it must simply be passed to the digestion functions and they will alter and interpret the context for you!
Definition:
typedef struct
{
    XMoshDigest digest;
    xmosh_byte *buffer;
    size_t bufferCursor;
    size_t bufferSize;
    xmosh_word64 msgLen;
    int corrupted;
    int status;
    char* errorMsg;
    int staticCtx;
    int staticBuffer;
} XMoshContext, XMoshCtx;
digest field: contains the current digest.
buffer field: reference to the data buffer storing undigested data.
bufferCursor field: holds the current buffer write positon.
bufferSize field: total size of the buffer.
msgLen field: total number of bytes passed into the digestion stream.
corrupted field: whether or not .

XMoshVersion

This union contains version information for either xmosh.h or for a module. It is comprised of a 4 byte length array with each byte representing a version which can also be interpreted as a 32-bit word for quick minimum compatibility comparison.

Developing modules

Developing XMosh modules is a relatively simple task. To start, make sure the XMOSH_MODULE symbol is defined for use by xmosh.h (which needs to be included). A number functions must be implemented, detailed below.

Meta data functions

EXPORT const char* getModuleDescription()
This function must return the address of a one line C string describing the module. Typically this will include the name of the module and author of the module.

EXPORT const char* getDigestAlgorithmName()
This function must return the address of a C string containing the official name of the algorithm being implemented. In example, a module implementing the SHA-2 512-bit sum algorithm would return reference to C string "SHA-512".

EXPORT const XMoshVersion* getModuleMinComplianceVersion()
This function returns the address of a XMoshVersion structure instance representing the minimum version of xmosh.h this module is compatible with.

EXPORT const XMoshVersion* getModuleVersion()
This function returns the address of a XMoshVersion structure instance representing the version number of this module.

Digest functions

EXPORT XMoshContext* initializeXMosh()
This function initializes and returns reference to a XMoshContext instance. This function should never return null. If there is an error during initialization the XMoshContext.status field should be set to XMOSH_STATUS_ERROR and an appropriate error message should be referenced by XMoshContext.errorMsg. If heap allocation fails, there should be a static instance of XMoshContext to refer to with an appropriate error message about the allocation failure. This is necessary, because implementations will be calling getLastError(XMoshContext*) to query for problems.
XMoshContext.status should be set to XMosh_STATUS_INIT if initialization is a success.
XMoshContext.corrupted should be set to 0.
XMoshContext.staticCtx should be set to 0 if context is on the stack and 1 if in the heap.
XMoshContext.staticBuffer should be set to 0 if the buffer is on the stack and 1 if it is in heap.

EXPORT void digestUpdate( XMoshContext*, xmosh_byte*, size_t )
This function is used to add data to be digested. This function should set XMoshContext.status to XMOSH_STATUS_INTER. If XMoshContext.status is XMOSH_STATUS_FINAL is set when this function is called, XMoshContext.status should be set to XMOSH_STATUS_ERROR and XMoshContext.corrupted should be set to 1 to indicate user error. This function should also check to make sure that XMOSH_STATUS_ERROR has not been set to avoid further problems.

EXPORT XMoshDigest* digestFinal( XMoshContext*, xmosh_byte*, size_t )
This function should perform the final steps of digestion and return reference to the sum. More data can be passed through this function, or the nifty NO_NEW_DATA macro can be used after the XMoshContext* parameter. This method may return NULL if there is an error. This function should also set XMoshContext.status should be set to XMOSH_STATUS_FINAL and should include similar error handling as digestUpdate( XMoshContext*, xmosh_byte*, size_t ).

Note that XMoshContext instances are only meant for one use, so support for resetting the context in anyway is unnecessary and undesired.



Please email me with any questions, bugs, concerns or just to say hi at drew@drew-buckley.com
Github page: https://github.com/drew-buckley/xmosh
Enjoy!