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 | |