Introduction
------------

Libknit is a crypto library written in C. It is designed to empower
the user with ciphers, hash and MAC algorithms through a small, strong
and easy to learn API.

Requirements
------------

- GCC
- libc

Installation
------------

./configure
make
make install
make clean

By default, the library is installed in /usr/lib and the header in /usr/include.

Compilation
-----------

gcc knit.c -lknit

Usage
-----

1. Include the header

	#include <knit.h>

2. Initialize memory

	KNIT knit = knit_new();

3. Set flags and values

	knit_set(...);

4. Do an operation

	knit_do(...);

5. Free memory

	knit_free(knit);

Functions Reference
-------------------

	knit_new()
	----------

		Syntax
		------

		KNIT knit_new();

		Description
		-----------

		Initializes memory.

		Example
		-------

		KNIT knit = knit_new();

		Return Value
		------------

		Returns a pointer to a zero-initialized structure in case of success or NULL in case of error.

	knit_free()
	-----------

		Syntax
		------

		void knit_free(KNIT knit);

		Description
		-----------

		Frees memory.

		Example
		-------

		knit_free(knit);

	knit_set()
	----------

		Syntax
		------

		void knit_set(KNIT knit, uint32_t flags, ...);

		Description
		-----------

		Sets flags and values.

		This function must be called before knit_do().

		Multiple flags in the same call must be ORed.

		Flags are divided in different groups. Flags in the same group cancel each other.
		This means that we can set an algorithm for ciphering and another for hashing, but
		we can't set 2 algorithms for ciphering	and 2 for hashing.

		Available flags:

			Ciphering
				KNIT_BLOWFISH
				KNIT_RC2
				KNIT_RC4

			Hashing
				KNIT_MD2
				KNIT_MD4
				KNIT_MD5

			MAC
				KNIT_HMAC

			Block Cipher Modes
				KNIT_ECB [default]
				KNIT_CBC
				KNIT_OFB

			Params
				KNIT_KEY
				KNIT_IV
				KNIT_EKB

		Flags under Params are a little bit different from the others.
		They don't cancel each other and they have to be followed by one or more additional arguments:

			KNIT_KEY

				If set, two additional arguments are expected, which are used to define the key and its byte length:

					void *k
					size_t k_length

			KNIT_IV

				If set, two additional arguments are expected, which are used to define the iv and its byte length:

					void *iv
					size_t iv_length

				This flag won't have any effect unless we set KNIT_CBC or KNIT_OFB.

			KNIT_EKB

				If set, one additional argument is expected, which is used to define the number of Effective Key Bits (EKB) for RC2:

					size_t ekb

				If not, it is set by default to k_length * 8.

		To use more than one of these flags in the same call, the given additional arguments must respect this order:

			k, k_length, iv, iv_length, ekb

		Examples
		--------

		knit_set(
			knit,
			KNIT_RC2 | KNIT_CBC | KNIT_KEY | KNIT_IV | KNIT_EKB,
			k, k_length,
			iv, iv_length,
			ekb
		);

		knit_set(
			knit,
			KNIT_RC2 | KNIT_KEY | KNIT_EKB,
			k, k_length,
			ekb
		);

		knit_set(
			knit,
			KNIT_RC2 | KNIT_OFB | KNIT_IV | KNIT_EKB,
			iv, iv_length,
			ekb
		);

		knit_set(
			knit,
			KNIT_BLOWFISH | KNIT_CBC | KNIT_KEY | KNIT_IV,
			k, k_length,
			iv, iv_length
		);

	knit_do()
	---------

		Syntax
		------

		uint8_t knit_do(KNIT knit, uint8_t op, void *x, size_t x_length, ...);

		Description
		-----------

		Executes op over x of x_length bytes.

		This function uses the flags and values set with knit_set() and it must be called after it.

		Allowed operations:

			KNIT_ENCRYPT

				If set, 2 additional arguments are expected, which are used to store the ciphertext and its byte length:

					uint8_t **c
					size_t *c_length

			KNIT_DECRYPT

				If set, 2 additional arguments are expected, which are used to store the plaintext and its byte length:

					uint8_t **p
					size_t *p_length

			KNIT_HASH

				If set, 1 additional argument is expected, which is used to store the digest:

					uint8_t **d

			KNIT_MAC

				If set, 1 additional argument is expected, which is used to store the tag:

					uint8_t **t

		Return Value
		------------

		Returns an 8-bit unsigned integer, which is equal to 0 in case of success or greater than 0 in case of error:

			0	KNIT_ERROR_OK
			1	KNIT_ERROR_NO_OP
			2	KNIT_ERROR_NO_ALGO
			3	KNIT_ERROR_NO_KEY
			4	KNIT_ERROR_NO_IV
			5	KNIT_ERROR_MIN_KEY_SIZE

		This value can be translated to a string with knit_error().

		Examples
		--------

		knit_do(knit, KNIT_ENCRYPT, x, x_length, &c, &c_length);

		knit_do(knit, KNIT_DECRYPT, x, x_length, &p, &p_length);

		knit_do(knit, KNIT_HASH, x, x_length, &d);

		knit_do(knit, KNIT_MAC, x, x_length, &t);

	knit_error()
	------------

		Syntax
		------

		uint8_t * knit_error(uint8_t errnum);

		Description
		-----------

		Translates an error number to an error string.

		Return Value
		------------

		Returns an error string if errnum is a valid error number or NULL otherwise.

		Example
		-------

		printf("%s\n", knit_error(knit_do(...)));

Examples
--------

	Blowfish Encryption/Decryption
	------------------------------

	#include <knit.h>

	int main() {

		uint8_t *c;
		uint8_t *p;

		size_t c_length;
		size_t p_length;

		KNIT knit = knit_new();

		knit_set(knit, KNIT_BLOWFISH | KNIT_KEY, "12345678", 8);

		if (!knit_do(knit, KNIT_ENCRYPT, "abcdefgh", 8, &c, &c_length))
			knit_do(knit, KNIT_DECRYPT, c, c_length, &p, &p_length);

		knit_free(knit);

		return 0;

	}

	MD4
	---

	#include <knit.h>

	int main() {

		uint8_t *d;

		KNIT knit = knit_new();

		knit_set(knit, KNIT_MD4);

		knit_do(knit, KNIT_HASH, "abcdefgh", 8, &d);

		knit_free(knit);

		return 0;

	}

	HMAC-MD5
	--------

	#include <knit.h>

	int main() {

		uint8_t *t;

		KNIT knit = knit_new();

		knit_set(knit, KNIT_MD5 | KNIT_HMAC | KNIT_KEY, "12345678", 8);

		knit_do(knit, KNIT_MAC, "abcdefgh", 8, &t);

		knit_free(knit);

		return 0;

	}

	RC2 Encryption CBC + MD5 + HMAC-MD5
	-----------------------------------
	
	#include <knit.h>

	int main() {

		uint8_t *x;
		uint8_t *c;
		uint8_t *d;
		uint8_t *t;

		size_t x_length;
		size_t c_length;

		x = (uint8_t *) "abcdefgh";
		x_length = 8;

		KNIT knit = knit_new();

		knit_set(
			knit,
			KNIT_RC2 | KNIT_CBC | KNIT_MD5 | KNIT_HMAC | KNIT_KEY | KNIT_IV,
			"12345678", 8,
			"abcdefgh", 8
		);

		if (
			knit_do(knit, KNIT_ENCRYPT, x, x_length, &c, &c_length) == KNIT_ERROR_OK &&
			knit_do(knit, KNIT_HASH, x, x_length, &d) == KNIT_ERROR_OK &&
			knit_do(knit, KNIT_MAC, x, x_length, &t) == KNIT_ERROR_OK
		) {
	
		}

		knit_free(knit);

		return 0;

	}

	RC4 Encryption
	--------------
	
	#include <knit.h>

	int main() {

		uint8_t *c;
	
		size_t c_length;
	
		KNIT knit = knit_new();

		knit_set(knit, KNIT_RC4 | KNIT_KEY, "12345678", 8);

		knit_do(knit, KNIT_ENCRYPT, "abcdefgh", 8, &c, &c_length);
	
		knit_free(knit);

		return 0;

	}

Other Constants
---------------

KNIT_BLOWFISH_BLOCK_SIZE   8
KNIT_BLOWFISH_MIN_KEY_SIZE 4
KNIT_BLOWFISH_MAX_KEY_SIZE 56

KNIT_RC2_BLOCK_SIZE   8
KNIT_RC2_MIN_KEY_SIZE 1
KNIT_RC2_MAX_KEY_SIZE 128

KNIT_RC4_MIN_KEY_SIZE 5
KNIT_RC4_MAX_KEY_SIZE 256

KNIT_MD2_BLOCK_SIZE  16
KNIT_MD2_DIGEST_SIZE 16

KNIT_MD4_BLOCK_SIZE  64
KNIT_MD4_DIGEST_SIZE 16

KNIT_MD5_BLOCK_SIZE  64
KNIT_MD5_DIGEST_SIZE 16

EOF
