aboutsummaryrefslogblamecommitdiffstats
path: root/libhashsum.h
blob: 8bf38c7b9f73efb27c3da4f2640cae4cbcefd125 (plain) (tree)
1
2
3
4
5
6
7
8
9






                                                         
                    
                    
 













                                                                   














                                                          





































                                                                                









                                                                          





























                                                                                 























































































                                         




                                       




                                       




























                                                             

                                                         























                                                                                          




                                                                                         




                                                                                         
                                                                                                                   




                                                 






                                                                                         





























                                                                                                                    

                                                









                                                                            

                                                









                                                                            

                                                









                                                                            

                                                









                                                                            

                                                









                                                                            

                                                









                                                                            

                                                








                                                                            
   

                                                









                                                                            

                                                








                                                                            
























































































                                                                                                    

      
/* See LICENSE file for copyright and license details. */
#ifndef LIBHASHSUM_H
#define LIBHASHSUM_H

#include <stddef.h>
#include <stdint.h>

#include <libsha1.h>
#include <libsha2.h>


#if defined(__GNUC__)
# define LIBHASHSUM_USERET_ __attribute__((__warn_unused_result__))
# define LIBHASHSUM_1_NONNULL_ __attribute__((__nonnull__(1)))
#else
# define LIBHASHSUM_USERET_
# define LIBHASHSUM_1_NONNULL_
#endif


/**
 * Hashing algorithm
 */
enum libhashsum_algorithm {
	LIBHASHSUM_MD2,         /**< MD2 */
	LIBHASHSUM_MD4,         /**< MD4 */
	LIBHASHSUM_MD5,         /**< MD5 */
	LIBHASHSUM_RIPEMD_128,  /**< RIPEMD-128 */
	LIBHASHSUM_RIPEMD_160,  /**< RIPEMD-160 */
	LIBHASHSUM_RIPEMD_256,  /**< RIPEMD-256 */
	LIBHASHSUM_RIPEMD_320,  /**< RIPEMD-320 */
	LIBHASHSUM_SHA0,        /**< SHA0 */
	LIBHASHSUM_SHA1,        /**< SHA1 */
	LIBHASHSUM_SHA_224,     /**< SHA-224 (SHA2) */
	LIBHASHSUM_SHA_256,     /**< SHA-256 (SHA2) */
	LIBHASHSUM_SHA_384,     /**< SHA-384 (SHA2) */
	LIBHASHSUM_SHA_512,     /**< SHA-512 (SHA2) */
	LIBHASHSUM_SHA_512_224, /**< SHA-512/224 (SHA2) */
	LIBHASHSUM_SHA_512_256  /**< SHA-512/256 (SHA2) */
};


/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_MD2`
 */
#define LIBHASHSUM_MD2_HASH_SIZE 16

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_MD4`
 */
#define LIBHASHSUM_MD4_HASH_SIZE 16

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_MD5`
 */
#define LIBHASHSUM_MD5_HASH_SIZE 16

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RIPEMD_128`
 */
#define LIBHASHSUM_RIPEMD_128_HASH_SIZE 16

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RIPEMD_160`
 */
#define LIBHASHSUM_RIPEMD_160_HASH_SIZE 20

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RIPEMD_256`
 */
#define LIBHASHSUM_RIPEMD_256_HASH_SIZE 32

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RIPEMD_320`
 */
#define LIBHASHSUM_RIPEMD_320_HASH_SIZE 40

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA0`
 */
#define LIBHASHSUM_SHA0_HASH_SIZE 20

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA1`
 */
#define LIBHASHSUM_SHA1_HASH_SIZE 20

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA_224`
 */
#define LIBHASHSUM_SHA_224_HASH_SIZE 28

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA_256`
 */
#define LIBHASHSUM_SHA_256_HASH_SIZE 32

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA_384`
 */
#define LIBHASHSUM_SHA_384_HASH_SIZE 48

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA_512`
 */
#define LIBHASHSUM_SHA_512_HASH_SIZE 64

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA_512_224`
 */
#define LIBHASHSUM_SHA_512_224_HASH_SIZE 28

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA_512_256`
 */
#define LIBHASHSUM_SHA_512_256_HASH_SIZE 32


/**
 * Hash state
 * 
 * For internal use
 */
union libhashsum_state {
	struct {
		unsigned char x[32];
		unsigned char mp[16];
		unsigned char mz[16];
		unsigned char sum[16];
		unsigned t;
	} md2;

	struct {
		union {
			uint32_t h32[4];
			uint8_t sum[16];
		} h;
		union {
			uint32_t m32[16];
			uint8_t m8[64];
		} m;
		uint64_t count;
	} md4;

	struct {
		union {
			uint32_t h32[4];
			uint8_t sum[16];
		} h;
		uint8_t m[64];
		uint32_t w[16];
		uint64_t count;
	} md5;

	struct {
		union {
			uint32_t h32[4];
			uint8_t sum[16];
		} h;
		union {
			uint32_t m32[16];
			uint8_t m8[64];
		} m;
		uint64_t count;
	} ripemd_128;

	struct {
		union {
			uint32_t h32[5];
			uint8_t sum[20];
		} h;
		union {
			uint32_t m32[16];
			uint8_t m8[64];
		} m;
		uint32_t w1[5];
		uint32_t w2[5];
		uint64_t count;
	} ripemd_160;

	struct {
		union {
			uint32_t h32[8];
			uint8_t sum[32];
		} h;
		union {
			uint32_t m32[16];
			uint8_t m8[64];
		} m;
		uint64_t count;
	} ripemd_256;

	struct {
		union {
			uint32_t h32[10];
			uint8_t sum[40];
		} h;
		union {
			uint32_t m32[16];
			uint8_t m8[64];
		} m;
		uint32_t w1[5];
		uint32_t w2[5];
		uint64_t count;
	} ripemd_320;

	struct {
		struct libsha1_state s;
		uint8_t sum[20];
	} sha0, sha1;

	struct {
		struct libsha2_state s;
		uint8_t sum[64];
	} sha2;
};


/**
 * Message hash functions and state
 */
struct libhashsum_hasher {
	/**
	 * The used hash algorithm
	 */
	enum libhashsum_algorithm algorithm;

	/**
	 * The number of bytes required for each
	 * call to `.process_block`
	 */
	size_t input_block_size;

	/**
	 * The number of bytes in the resulting hash
	 */
	size_t hash_size;

	/**
	 * The hash
	 * 
	 * This will be set to `NULL` when the structure
	 * is initialised, but will be set to a pointer
	 * to a buffer inside `.state` once `.finalise_const`
	 * or `.finalise` has been called with successful
	 * completion
	 */
	unsigned char *hash_output;

	/**
	 * Whether the algorithm supports non-whole octet input
	 */
	unsigned char supports_non_whole_bytes;

	/**
	 * Update the hash state given additional
	 * input data
	 * 
	 * @param   this   The object containing this function pointer
	 * @param   data   The new input data
	 * @param   bytes  The number of bytes available in `data`
	 * @return         The number of bytes processed from `data`
	 */
	LIBHASHSUM_USERET_ LIBHASHSUM_1_NONNULL_
	size_t (*process)(struct libhashsum_hasher *this, const void *data, size_t bytes);

	/**
	 * Update the hash state given it's final
	 * input data
	 * 
	 * @param   this        The object containing this function pointer
	 * @param   data        The new input data, the function may rewrite it's content
	 * @param   bytes       The number of bytes available in `data` for reading
	 * @param   extra_bits  Additional bits in `data` not covered by `bytes`
	 * @return              0 on success, -1 on failure
	 * 
	 * @throws  EINVAL  `extra_bits` is greater than 7
	 * @throws  EINVAL  `extra_bits` is non-zero but `.supports_non_whole_bytes` is 0
	 */
	LIBHASHSUM_1_NONNULL_
	int (*finalise_const)(struct libhashsum_hasher *this, const void *data, size_t bytes, unsigned extra_bits);

	/**
	 * Update the hash state given it's final
	 * input data
	 * 
	 * @param   this        The object containing this function pointer
	 * @param   data        The new input data, the function may rewrite it's content
	 * @param   bytes       The number of bytes available in `data` for reading
	 * @param   extra_bits  Additional bits in `data` not covered by `bytes`
	 * @param   size        `bytes` plus any number of additional bytes available
	 *                      for the function to write additional data block padding
	 * @return              0 on success, -1 on failure
	 * 
	 * @throws  EINVAL  `extra_bits` is greater than 7
	 * @throws  EINVAL  `extra_bits` is non-zero but `.supports_non_whole_bytes` is 0
	 */
	LIBHASHSUM_1_NONNULL_
	int (*finalise)(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extra_bits, size_t size);

	/**
	 * The hash state
	 * 
	 * For internal use
	 */
	union libhashsum_state state;
};


/**
 * Create an initialised state for a hash algorithm
 * and return hash functions and details
 * 
 * @param   this       The output parameter for the functions, details, and state
 * @param   algorithm  The hashing algorithm
 * @return             0 on success, -1 on failure
 * 
 * @throws  EINVAL  `algorithm` is unsupported
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_hasher(struct libhashsum_hasher *this, enum libhashsum_algorithm algorithm);

/**
 * Create an initialised state for MD2
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * Failure isn't actually possible, so this function always return 0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_md2_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for MD4
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * Failure isn't actually possible, so this function always return 0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_md4_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for MD5
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * Failure isn't actually possible, so this function always return 0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_md5_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for RIPEMD-128
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * Failure isn't actually possible, so this function always return 0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_ripemd_128_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for RIPEMD-160
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * Failure isn't actually possible, so this function always return 0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_ripemd_160_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for RIPEMD-256
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * Failure isn't actually possible, so this function always return 0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_ripemd_256_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for RIPEMD-320
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * Failure isn't actually possible, so this function always return 0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_ripemd_320_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA0
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * Failure isn't actually possible, so this function always return 0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha0_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA1
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * Failure isn't actually possible, so this function always return 0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha1_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA-224 (SHA2)
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * Failure isn't actually possible, so this function always return 0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha_224_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA-256 (SHA2)
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * Failure isn't actually possible, so this function always return 0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha_256_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA-384 (SHA2)
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * Failure isn't actually possible, so this function always return 0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha_384_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA-512 (SHA2)
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * Failure isn't actually possible, so this function always return 0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha_512_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA-512/224 (SHA2)
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * Failure isn't actually possible, so this function always return 0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha_512_224_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA-512/256 (SHA2)
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * Failure isn't actually possible, so this function always return 0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha_512_256_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA2
 * hashing and return hash functions and details
 * 
 * @param   this      The output parameter for the functions, details, and state
 * @param   algobits  32 for a 32-bit algorithm, 64 for a 64-bit algorithm
 * @param   hashbits  Hash output size in bits
 * @return            0 on success, -1 on failure
 * 
 * @throws  EINVAL  `algobits` is invalid (neither 32 nor 64)
 * @throws  EINVAL  `hashbits` is invalid (neither 224, 256, 384, nor 512)
 * @throws  EINVAL  The combination of `algobits` and `hashbits` is invalid
 *                  (`hashbits` is 384 or 512 but `algobits` is 32)
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha2_hasher(struct libhashsum_hasher *this, unsigned algobits, size_t hashbits);


#endif