xref: /xnu-12377.1.9/EXTERNAL_HEADERS/corecrypto/ccmode_siv_hmac.h (revision f6217f891ac0bb64f3d375211650a4c1ff8ca1ea)
1 /* Copyright (c) (2019-2022) Apple Inc. All rights reserved.
2  *
3  * corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which
4  * is contained in the License.txt file distributed with corecrypto) and only to
5  * people who accept that license. IMPORTANT:  Any license rights granted to you by
6  * Apple Inc. (if any) are limited to internal use within your organization only on
7  * devices and computers you own or control, for the sole purpose of verifying the
8  * security characteristics and correct functioning of the Apple Software.  You may
9  * not, directly or indirectly, redistribute the Apple Software or any portions thereof.
10  */
11 
12 #ifndef _CORECRYPTO_CCMODE_SIV_HMAC_H
13 #define _CORECRYPTO_CCMODE_SIV_HMAC_H
14 
15 #include <corecrypto/cc.h>
16 #include <corecrypto/ccmode.h>
17 #include <corecrypto/ccmode_impl.h>
18 #include <corecrypto/ccdigest.h>
19 #include <corecrypto/cchmac.h>
20 #include <corecrypto/ccsha2.h>
21 
22 #define ccsiv_hmac_ctx_decl(_size_, _name_) cc_ctx_decl_vla(ccsiv_hmac_ctx, _size_, _name_)
23 #define ccsiv_hmac_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
24 
25 /*!
26  @function   ccsiv_hmac_context_size
27  @abstract   Return size of context
28 
29  @param      mode       Descriptor for the mode
30  */
31 size_t ccsiv_hmac_context_size(const struct ccmode_siv_hmac *mode);
32 
33 /*!
34  @function   ccsiv_hmac_block_size
35  @abstract   Return size of context
36 
37  @param      mode       Descriptor for the mode
38  */
39 size_t ccsiv_hmac_block_size(const struct ccmode_siv_hmac *mode);
40 
41 /*!
42  @function   ccsiv_hmac_ciphertext_size
43  @abstract   Return size of Ciphertext (which is the ciphertext and corresponding tag) given the mode and plaintext length
44 
45  @param      ctx               Current siv_hmac context that has been previously initialized
46  @param      plaintext_size    Size of the plaintext
47 
48  @discussion returns the length of the aead ciphertext that the context will generate which includes both the encrypted plaintext
49  and tag.
50  */
51 size_t ccsiv_hmac_ciphertext_size(ccsiv_hmac_ctx *ctx, size_t plaintext_size);
52 
53 /*!
54  @function   ccsiv_hmac_plaintext_size
55  @abstract   Return size of plaintext given a ciphertext length and mode.
56 
57  @param      ctx               Current siv_hmac context that has been previously initialized
58  @param      ciphertext_size    Size of the ciphertext (which includes the tag)
59 
60  @discussion returns the length of the plaintext which results from the decryption of a ciphertext of the corresponding size (here ciphertext size includes the tag).
61  */
62 size_t ccsiv_hmac_plaintext_size(ccsiv_hmac_ctx *ctx, size_t ciphertext_size);
63 
64 /*!
65  @function   ccsiv_hmac_init
66  @abstract   Initialize a context for siv_hmac with an associated mode, given key and specifying output tag size.
67 
68  @param      mode               Descriptor for the mode
69  @param      ctx                Alocated context to be intialized
70  @param      key_byte_len       Length of the key:  Supported key sizes are 32, 48, 64 bytes
71  @param      key                key for siv_hmac
72  @param      tag_size           The length of the output tag requested. Must be at least 20 bytes, and can be as large as the
73  associated digest's output
74 
75  @discussion In order to  compute HMAC_SIV_Enc_k(a1,...,am, n, x) where ai is the ith piece of associated data, n is a nonce and x
76  is a plaintext, we first initialize the context with this call, and then use it to call ccsiv_hmac_aad for each ai, followed by
77  ccsiv_hmac_set_nonce for nonce n, and finally a call to ccsiv_hmac_crypt for the plaintext x. Note the order of the calls to aad,
78  nonce and then crypt is critical. If a second encryption is needed then a call to ccsiv_hmac_reset can be used to reset state,
79  and begin again.
80  */
81 int ccsiv_hmac_init(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx, size_t key_byte_len, const uint8_t *key, size_t tag_size);
82 
83 /*!
84  @function   ccsiv_hmac_aad
85  @abstract   Add the next piece of associated data to the hmac_siv's computation of the tag. Note this call is optional and no
86  associated data needs to be provided. Multiple pieces of associated data can be provided by multiple calls to this
87  function. Each input is regarded as a separate piece of associated data, and the mac is NOT simply computed on the
88  concatenation of all of the associated data inputs. Therefore on decryption the same inputs must be provided in
89  the same order.
90 
91  @param      mode               Descriptor for the mode
92  @param      ctx                Intialized ctx
93  @param      nbytes             Length of the current associated data being added
94  @param      in                 Associated data to be authenticated.
95 
96  @discussion Adds the associated data given by in to the computation of the tag in the associated data.
97  */
98 int ccsiv_hmac_aad(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in);
99 
100 /*!
101  @function   ccsiv_hmac_nonce
102  @abstract   Add the nonce to the hmac_siv's computation of the the tag. Changes the internal state of the context
103  so that after the call only a crypt or reset call is permitted.
104  @param      mode               Descriptor for the mode
105  @param      ctx                Intialized ctx
106  @param      nbytes             Length of the current nonce data being added
107  @param      in                 Nonce data to be authenticated.
108 
109  @discussion The nonce is a special form of authenticated data. If provided ( a call to hmac_nonce is optional) it allows
110  randomization of the ciphertext (preventing deterministic encryption). While the length of the nonce is not limited, the
111  amount of entropy that can be provided is limited by the number of bits in the block of the associated block-cipher in mode.
112  */
113 int ccsiv_hmac_set_nonce(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in);
114 
115 /*!
116  @function   ccsiv_hmac_crypt
117  @abstract   Depending on whether mode has been setup to encrypt or decrypt, this function
118  1) Encrypts the plaintext given as input in, and provides the ciphertext (which is a concatenation of the tag
119  followed by the encrypted plaintext) as output out. 2) Decrypts plaintext using the input ciphertext at in (which again is the
120  tag, followed by encrypted plaintext), and then verifies that the computer tag and provided tags match.
121  @param      mode               Descriptor for the mode
122  @param      ctx                Intialized ctx
123  @param      nbytes             Case 1) Length of the current plaintext
124  Case 2) Length of the current ciphertext (tag length + plaintext length)
125  @param      in                 Case 1) Plaintext
126  Case 2) Ciphertext
127  @discussion This function is only called once. If one wishes to compute another (en)/(de)cryption, one resets the state with
128  ccsiv_hmac_reset, and then begins the process again. There is no way to stream large plaintext/ciphertext inputs into the
129  function.
130  @param     out           Case1)  Tag+ Ciphertext (buffer should be already allocated and of length tag + plaintext length)
131                     Case 2) Plaintext (buffer should be already allocated and of length ciphertext - tag length
132 
133  In the case of a decryption, if there is a failure in verifying the computed tag against the provided tag (embedded int he ciphertext), then a decryption/verification
134  failure is returned, and any internally computed plaintexts and tags are zeroed out.
135  Lastly the contexts internal state is reset, so that a new decryption/encryption can be commenced.
136  */
137 int ccsiv_hmac_crypt(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in, uint8_t *out);
138 
139 /*!
140  @function   ccsiv_hmac_reset
141  @abstract   Resets the state of the siv_hamc ctx, maintaining the key, but preparing  the
142  ctx to preform a new Associated Data Authenticated (En)/(De)cryption.
143  @param      mode               Descriptor for the mode
144  @param      ctx                Intialized ctx
145  */
146 int ccsiv_hmac_reset(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx);
147 
148 /*!
149  @function   ccsiv_hmac_one_shot
150  @abstract   A simplified but more constrained way of performing an AEAD SIV HMAC (en)/(de)cryption. It is limited because only
151  one piece of associated data may be provided.
152  @param      mode               Descriptor for the mode
153  @param      key_len            Length of the key:  Supported key sizes are 32, 48, 64 bytes
154  @param      key                key for siv_hmac
155  @param      tag_length         The length of the tag to produce or accept as input. Must be at least 20
156  bytes, and can be as large as the hmac's digest's output
157  @param      nonce_nbytes       Length of the current nonce data being added
158  @param      nonce              Nonce data to be authenticated.
159  @param      adata_nbytes       Length of the associated data.
160  @param      adata              Associated data to be authenticated.
161  @param      in_nbytes          Length of either the plaintext (for encryption) or ciphertext (for decryption)
162  @param      in                 plaintext or ciphertext. Note that the ciphertext includes a tag of length tag_length prepended to it.
163  @param      out                Buffer to hold ciphertext/plaintext. (Note Ciphertext is of size plaintext length + tag_length and plaintext is of length ciphertext - tag_length.)
164  */
165 
166 // One shot AEAD with only one input for adata, and a nonce.
167 int ccsiv_hmac_one_shot(const struct ccmode_siv_hmac *mode,
168                         size_t key_len,
169                         const uint8_t *key,
170                         size_t tag_length,
171                         unsigned nonce_nbytes,
172                         const uint8_t *nonce,
173                         unsigned adata_nbytes,
174                         const uint8_t *adata,
175                         size_t in_nbytes,
176                         const uint8_t *in,
177                         uint8_t *out);
178 
179 #endif /* _CORECRYPTO_CCMODE_SIV_HMAC_H */
180