saturnin.h 4.56 KB
Newer Older
lwc-tester committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
#ifndef saturnin_h__
#define saturnin_h__

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

/*
 * Saturnin-CTR-Cascade context. This is allocated by the caller in any
 * emplacement (stack, heap, static data...). Precise semantics of the
 * context fields are not part of the API.
 */
typedef struct {
	uint32_t keybuf[16];
	uint8_t cascade[32];
	uint8_t ctr[32];
	uint8_t buf[32];
	size_t ptr;
} saturnin_aead_context;

/*
 * Initialize an AEAD context with a given key. The caller must make
 * sure to provide only a valid key length. Saturnin expects a key of
 * exactly 32 bytes.
 */
void saturnin_aead_init(saturnin_aead_context *cc,
	const void *key, size_t key_len);

/*
 * Reset a context for a new AEAD computation, with the key which was
 * set with the last saturnin_aead_init() call on that context.
 *
 * The caller must provide a valid nonce. Saturnin accepts all nonce
 * lengths from 0 to 20 bytes (inclusive).
 */
void saturnin_aead_reset(saturnin_aead_context *cc,
	const void *nonce, size_t nonce_len);

/*
 * Inject some associated authenticated data (AAD), to be part of the
 * authentication tag processing. This call must occur after
 * saturnin_aead_reset(), but before saturnin_aead_flip(). The AAD may
 * be injected in several calls with chunks of arbitrary length. If
 * there is no AAD to inject, it is not necessary to call this function.
 */
void saturnin_aead_aad_inject(saturnin_aead_context *cc,
	const void *aad, size_t aad_len);

/*
 * Finish processing of the AAD, and start encryption or decryption of
 * data.
 */
void saturnin_aead_flip(saturnin_aead_context *cc);

/*
 * Encrypt (if encrypt != 0) or decrypt (if encrypt == 0) some data.
 * This call should occur after saturnin_aead_flip(). Processing is
 * performed in-place (the output data replaces the input data). The
 * message data may be processed in several calls with chunks of
 * arbitrary length. If there is no message data (i.e. the AEAD is used
 * only as a MAC over the AAD), then it is not necessary to call this
 * function.
 *
 * If a single message is processed in several chunks, then all calls
 * should agree on the 'encrypt' flag.
 */
void saturnin_aead_run(saturnin_aead_context *cc,
	int encrypt, void *data, size_t data_len);

/*
 * Finish processing of a message, producing an authentication tag of the
 * specified length. The caller is responsible for asking only for valid
 * tag lengths. Saturnin can produce tags of 0 to 32 bytes (inclusive).
 *
 * (Of course, empty or short tags provide no or weak security against
 * forgeries.)
 *
 * Once this function has been called, the processing of the message is
 * finished (in particular, calling this function again immediately after
 * will not necessarily yield the same tag value). Such a context can
 * be reset (with saturnin_aead_reset()) to process another message with
 * the same key, or reinitialized (with saturnin_aead_init()) to process
 * another message with a different key.
 */
void saturnin_aead_get_tag(saturnin_aead_context *cc,
	void *tag, size_t tag_len);

/*
 * This is a variant of saturnin_aead_get_tag(); it internally calls
 * saturnin_aead_get_tag(). However, instead of returning the computed
 * tag, it compares the tag with the provided value. Returned value is
 * 1 if the tags match, 0 otherwise. This is intended to be used when
 * an encrypted message is received. If a value of 0 is returned, then
 * the message and/or the tag is altered, and the message contents
 * shall be discarded.
 */
int saturnin_aead_check_tag(saturnin_aead_context *cc,
	const void *tag, size_t tag_len);

/*
 * Saturnin-Hash context. This is allocated by the caller in any
 * emplacement (stack, heap, static data...). Precise semantics of the
 * context fields are not part of the API.
 */
typedef struct {
	uint8_t state[32];
	uint8_t buf[32];
	size_t ptr;
} saturnin_hash_context;

/*
 * Initialize a context for a new hash computation.
 */
void saturnin_hash_init(saturnin_hash_context *hc);

/*
 * Process some bytes with the hash function. The complete message to
 * be hashed can be processed in several calls with arbitrary chunk
 * length.
 */
void saturnin_hash_update(saturnin_hash_context *hc,
	const void *data, size_t data_len);

/*
 * Finalize the hash computation and write the output into the out[]
 * buffer. The hash output length depends on the implemented function
 * (Saturnin-Hash produces 32 bytes).
 *
 * The context is NOT modified by this call; this allows obtained
 * "partial hashes" (hash value of all data injected so far) without
 * interrupting a running hash computation.
 */
void saturnin_hash_out(const saturnin_hash_context *hc,
	void *out);

#endif