@@ -2576,6 +2576,166 @@ \subsection{One--Shot Packet}
25762576In order to enable OpenSSH compatibility, the flag \textit {CHACHA20POLY1305\_ OPENSSH\_ COMPAT } has to be \textbf {OR }'ed into
25772577the \textit {direction } parameter.
25782578
2579+
2580+ \mysection {SIV}
2581+ \label {SIV }
2582+
2583+ The SIV (Synthetic Initialization Vector) authenticated encryption is a block cipher mode of encryption
2584+ defined by \url {https://tools.ietf.org/html/rfc5297}.
2585+
2586+ In contrast to all the other AEAD modes, SIV provides no iterative API. Instead it only provides one--shot APIs.
2587+
2588+ AEAD algorithm design usually suggests using a separate Nonce (also called IV) and additional authenticated Data (AAD).
2589+ SIV treats this slightly different and does not enforce any of the two, but leaves it up to the user.
2590+ Also SIV allows passing multiple sets of data as AAD, up to a maximum of \texttt {126 } elements.
2591+ In case one wants to use a Nonce in a classical style it is suggested to pass it as the last of the AAD elements,
2592+ thereby limiting the number of AAD to \texttt {125 }.
2593+
2594+ \subsection {Encryption / Decryption }
2595+ To encrypt and create a tag resp. decrypt and check the tag, the following API functions can be used.
2596+
2597+ \index {siv\_ encrypt\_ memory()}
2598+ \begin {verbatim }
2599+ int siv_encrypt_memory( int cipher,
2600+ const unsigned char *key, unsigned long keylen,
2601+ const unsigned char *ad[], unsigned long adlen[],
2602+ const unsigned char *pt, unsigned long ptlen,
2603+ unsigned char *ct, unsigned long *ctlen);
2604+ \end {verbatim }
2605+ This encrypts the data where \textit {pt } is the plaintext and \textit {ct } is the ciphertext.
2606+ The length of the plaintext is given in \textit {ptlen } and the length of the ciphertext is given in \textit {ctlen }.
2607+ \textit {ctlen } shall contain the max buffer size allocated at \textit {ct } on input, and will be updated with the
2608+ written length on successful encryption.
2609+
2610+ The buffer of \textit {ct } shall be at least \texttt {ptlen + 16 } bytes wide.
2611+
2612+ The key to the encrypt operation is passed in \textit {key } of length \textit {keylen }.
2613+
2614+ The AAD is passed as array of pointers in \textit {ad }. The length of each AAD is passed as array of
2615+ \textit {unsigned long } in \textit {adlen }.
2616+ As soon as an array element of \textit {ad } is hit which equals \texttt {NULL } or an array element of \textit {adlen }
2617+ is hit which equals \texttt {0 }, processing of the AAD is stopped.
2618+
2619+ \index {siv\_ decrypt\_ memory()}
2620+ \begin {verbatim }
2621+ int siv_decrypt_memory( int cipher,
2622+ const unsigned char *key, unsigned long keylen,
2623+ const unsigned char *ad[], unsigned long adlen[],
2624+ const unsigned char *ct, unsigned long ctlen,
2625+ unsigned char *pt, unsigned long *ptlen);
2626+ \end {verbatim }
2627+ This decrypts the data where \textit {ct } is the ciphertext of length \textit {ctlen } and \textit {pt } is the plaintext of length \textit {ptlen }.
2628+ \textit {ptlen } shall contain the max buffer size allocated at \textit {pt } on input, and will be updated with the
2629+ written lenth on successful decryption.
2630+
2631+ The buffer of \textit {pt } shall be at least \texttt {ctlen - 16 } bytes wide.
2632+
2633+ The AAD is processed in the same way as in the encrypt function.
2634+
2635+ An example of encryption and decryption with SIV using multiple AAD and a Nonce is given below.
2636+
2637+ \begin {small }
2638+ \begin {verbatim }
2639+ #include <tomcrypt.h>
2640+
2641+ int main(void)
2642+ {
2643+ int err;
2644+ unsigned char plain[16] = {0};
2645+ unsigned char ct[sizeof(plain) + 16] = {0};
2646+ unsigned long plainlen = sizeof(plain), ctlen = sizeof(ct);
2647+
2648+ register_cipher(&aes_desc);
2649+
2650+ /* We need to cast the AAD strings because the API asks for an `unsigned char*`
2651+ * but a string is on most platforms defined as a "signed" `char*`. */
2652+ if ((err = siv_encrypt_memory(find_cipher("aes"),
2653+ ((unsigned char[32]) {0x0}), 32,
2654+ ((const unsigned char*[]) {(void*)"aad0", (void*)"aad1",
2655+ (void*)"NONCE", NULL}),
2656+ ((unsigned long[]) {4, 4, 5, 0}),
2657+ plain, plainlen,
2658+ ct, &ctlen)) != CRYPT_OK) {
2659+ whine_and_pout(err);
2660+ }
2661+
2662+ if ((err = siv_decrypt_memory(find_cipher("aes"),
2663+ ((unsigned char[32]) {0x0}), 32,
2664+ ((const unsigned char*[]) {(void*)"aad0", (void*)"aad1",
2665+ (void*)"NONCE", NULL}),
2666+ ((unsigned long[]) {4, 4, 5, 0}),
2667+ ct, ctlen,
2668+ plain, &plainlen)) != CRYPT_OK) {
2669+ whine_and_pout(err);
2670+ }
2671+
2672+ return EXIT_SUCCESS;
2673+ }
2674+ \end {verbatim }
2675+ \end {small }
2676+
2677+ \subsection {One--Shot Packet }
2678+ To process a single packet under any given key the following helper function can be used.
2679+
2680+ \index {siv\_ memory()}
2681+ \begin {verbatim }
2682+ int siv_memory( int cipher, int direction,
2683+ const unsigned char *key, unsigned long keylen,
2684+ const unsigned char *in, unsigned long inlen,
2685+ unsigned char *out, unsigned long *outlen,
2686+ ...);
2687+ \end {verbatim }
2688+
2689+ This will execute a SIV operation of the \textit {direction } (\texttt {LTC\_ ENCRYPT } resp. \texttt {LTC\_ DECRYPT })
2690+ using the \textit {cipher } with the \textit {key } of len \textit {keylen }.
2691+ The AAD is optionally passed as varargs of the form \textit {(const unsigned char*, unsigned long) }, which musst be
2692+ NULL terminated.
2693+ The input is passed via the \textit {in } argument of length \textit {inlen }.
2694+ The output is stored in the buffer pointer to by the \textit {out } argument where the length is passed as \textit {outlen }.
2695+ \textit {outlen } shall contain the initial size of the buffer behind \textit {out } when calling the function and on
2696+ return it will contain the written size.
2697+
2698+ In case the operation is \textit {encryption } the buffer of \textit {out } shall be at least \texttt {inlen + 16 } bytes wide.
2699+ In the case of \textit {decryption } the buffer of \textit {out } shall be at least \texttt {inlen - 16 } bytes wide.
2700+
2701+ An example of encryption and decryption with the one--shot API of SIV using multiple AAD is given below.
2702+
2703+ \begin {small }
2704+ \begin {verbatim }
2705+ #include <tomcrypt.h>
2706+
2707+ int main(void)
2708+ {
2709+ int err;
2710+ unsigned char plain[16] = {0};
2711+ unsigned char ct[sizeof(plain) + 16] = {0};
2712+ unsigned long plainlen = sizeof(plain), ctlen = sizeof(ct);
2713+
2714+ register_cipher(&aes_desc);
2715+
2716+ /* Note that constant length values must be suffixed by `uL` in order
2717+ * to operate correctly cross-platform. */
2718+ if ((err = siv_memory(find_cipher("aes"), LTC_ENCRYPT,
2719+ ((unsigned char[32]) {0x0}), 32,
2720+ plain, plainlen,
2721+ ct, &ctlen,
2722+ "aad0", 4uL, "aad1", 4uL, "NONCE", 5uL, NULL)) != CRYPT_OK) {
2723+ whine_and_pout(err);
2724+ }
2725+
2726+ if ((err = siv_memory(find_cipher("aes"), LTC_DECRYPT,
2727+ ((unsigned char[32]) {0x0}), 32,
2728+ ct, ctlen,
2729+ plain, &plainlen,
2730+ "aad0", 4uL, "aad1", 4uL, "NONCE", 5uL, NULL)) != CRYPT_OK) {
2731+ whine_and_pout(err);
2732+ }
2733+
2734+ return EXIT_SUCCESS;
2735+ }
2736+ \end {verbatim }
2737+ \end {small }
2738+
25792739\chapter {One-Way Cryptographic Hash Functions }
25802740\mysection {Core Functions}
25812741Like the ciphers, there are hash core functions and a universal data type to hold the hash state called \textit {hash\_ state }. To initialize hash
0 commit comments