@@ -2576,6 +2576,166 @@ \subsection{One--Shot Packet}
2576
2576
In order to enable OpenSSH compatibility, the flag \textit {CHACHA20POLY1305\_ OPENSSH\_ COMPAT } has to be \textbf {OR }'ed into
2577
2577
the \textit {direction } parameter.
2578
2578
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
+
2579
2739
\chapter {One-Way Cryptographic Hash Functions }
2580
2740
\mysection {Core Functions}
2581
2741
Like 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