Software APIs
aes_gcm.h
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #ifndef OPENTITAN_SW_DEVICE_LIB_CRYPTO_IMPL_AES_GCM_AES_GCM_H_
6 #define OPENTITAN_SW_DEVICE_LIB_CRYPTO_IMPL_AES_GCM_AES_GCM_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
13 #include "sw/device/lib/crypto/drivers/aes.h"
14 #include "sw/device/lib/crypto/impl/aes_gcm/ghash.h"
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif // __cplusplus
19 
20 /**
21  * AES-GCM context object for streaming operations.
22  */
23 typedef struct aes_gcm_context {
24  /**
25  * Whether this is an encryption operation (false indicates decryption).
26  */
28  /**
29  * Underlying AES-CTR key.
30  */
32  /**
33  * Initial counter block (J0 in the spec).
34  */
36  /**
37  * Current counter block for the main GCTR operation over the plaintext.
38  */
40  /**
41  * Length of the associated data received so far, in bytes.
42  */
43  size_t aad_len;
44  /**
45  * Length of the input so far, in bytes.
46  */
47  size_t input_len;
48  /**
49  * Partial GHASH block.
50  *
51  * Length is always equal to `aad_len % kGhashBlockNumBytes` if the state is
52  * `kAesGcmStateUpdateAad`, and is always 0 if the state
53  * is `kAesGcmStateUpdateEncryptedData` (since ciphertext gets accumulated in
54  * full-block increments). The block may be empty, but will never be full.
55  */
57  /**
58  * Partial input block.
59  *
60  * Length is always equal to `input_len % kAesBlockNumBytes`; the block may
61  * be empty, but will never be full.
62  */
64  /**
65  * Current context for the tag's ongoing GHASH computation.
66  */
68 } __attribute__((aligned(sizeof(uint32_t)))) aes_gcm_context_t;
69 
70 /**
71  * AES-GCM authenticated encryption as defined in NIST SP800-38D, algorithm 4.
72  *
73  * The key is represented as two shares which are XORed together to get the
74  * real key value. The IV must be either 96 or 128 bits.
75  *
76  * If the key is a sideloaded key, it is the caller's responsibility to load
77  * and clear it.
78  *
79  * The byte-lengths of the plaintext and AAD must each be < 2^32. This is a
80  * tighter constraint than the length limits in section 5.2.1.1.
81  *
82  * This implementation does not support short tags.
83  *
84  * @param key AES key
85  * @param iv_len length of IV in 32-bit words
86  * @param iv IV value (may be NULL if iv_len is 0)
87  * @param plaintext_len length of plaintext in bytes
88  * @param plaintext plaintext value (may be NULL if plaintext_len is 0)
89  * @param aad_len length of AAD in bytes
90  * @param aad AAD value (may be NULL if aad_len is 0)
91  * @param tag_len Tag length in 32-bit words
92  * @param[out] tag Output buffer for tag
93  * @param[out] ciphertext Output buffer for ciphertext (same length as
94  * plaintext)
95  * @return Error status; OK if no errors
96  */
98 status_t aes_gcm_encrypt(const aes_key_t key, const size_t iv_len,
99  const uint32_t *iv, const size_t plaintext_len,
100  const uint8_t *plaintext, const size_t aad_len,
101  const uint8_t *aad, const size_t tag_len,
102  uint32_t *tag, uint8_t *ciphertext);
103 
104 /**
105  * AES-GCM authenticated decryption as defined in NIST SP800-38D, algorithm 5.
106  *
107  * The key is represented as two shares which are XORed together to get the
108  * real key value. The IV must be either 96 or 128 bits.
109  *
110  * If the key is a sideloaded key, it is the caller's responsibility to load
111  * and clear it.
112  *
113  * The byte-lengths of the plaintext and AAD must each be < 2^32. This is a
114  * tighter constraint than the length limits in section 5.2.1.1.
115  *
116  * If authentication fails, this function will return `kHardenedBoolFalse` for
117  * the `success` output parameter, and the plaintext should be ignored. Note
118  * the distinction between the `success` output parameter and the return value
119  * (type `status_t`): the return value indicates whether there was an
120  * internal error while processing the function, and `success` indicates
121  * whether the authentication check passed. If the return value is anything
122  * other than OK, all output from this function should be discarded, including
123  * `success`.
124  *
125  * @param key AES key
126  * @param iv_len length of IV in 32-bit words
127  * @param iv IV value (may be NULL if iv_len is 0)
128  * @param ciphertext_len length of ciphertext in bytes
129  * @param ciphertext plaintext value (may be NULL if ciphertext_len is 0)
130  * @param aad_len length of AAD in bytes
131  * @param aad AAD value (may be NULL if aad_len is 0)
132  * @param tag_len Tag length in 32-bit words
133  * @param tag Authentication tag
134  * @param[out] plaintext Output buffer for plaintext (same length as ciphertext)
135  * @param[out] success True if authentication was successful, otherwise false
136  * @return Error status; OK if no errors
137  */
139 status_t aes_gcm_decrypt(const aes_key_t key, const size_t iv_len,
140  const uint32_t *iv, const size_t ciphertext_len,
141  const uint8_t *ciphertext, const size_t aad_len,
142  const uint8_t *aad, const size_t tag_len,
143  const uint32_t *tag, uint8_t *plaintext,
144  hardened_bool_t *success);
145 
146 /**
147  * Starts an AES-GCM authenticated encryption operation.
148  *
149  * Populates the `ctx` parameter with initial values.
150  *
151  * If the key is a sideloaded key, it is the caller's responsibility to load
152  * and clear it.
153  *
154  * Typical usage looks like this (the `update_encrypted_data` and `update_aad`
155  * calls cannot be interleaved with each other; you must pass all the
156  * associated data before adding encrypted data):
157  * aes_gcm_encrypt_init(...)
158  * aes_gcm_update_aad(...) // call 0 or more times
159  * aes_gcm_update_encrypted_data(...) // call 0 or more times
160  * aes_gcm_encrypt_final(...)
161  *
162  * @param key AES key
163  * @param iv_len length of IV in 32-bit words
164  * @param iv IV value (may be NULL if iv_len is 0)
165  * @param[out] ctx AES-GCM context object.
166  * @return Error status; OK if no errors
167  */
169 status_t aes_gcm_encrypt_init(const aes_key_t key, const size_t iv_len,
170  const uint32_t *iv, aes_gcm_context_t *ctx);
171 
172 /**
173  * Updates the associated data for an AES-GCM operation.
174  *
175  * @param ctx AES-GCM context object.
176  * @param aad_len length of aad in bytes
177  * @param aad aad value (may be NULL if aad_len is 0)
178  * @return Error status; OK if no errors
179  */
181 status_t aes_gcm_update_aad(aes_gcm_context_t *ctx, const size_t aad_len,
182  const uint8_t *aad);
183 
184 /**
185  * Updates the encrypted input for an AES-GCM operation.
186  *
187  * For encryption, this updates the plaintext. For decryption, it updates the
188  * ciphertext.
189  *
190  * If the key is a sideloaded key, it is the caller's responsibility to load
191  * and clear it.
192  *
193  * Updates the context and returns output that corresponds to (full blocks
194  * of) the new chunk of input. The output buffer must have enough space to
195  * hold all full blocks that could be produced; rounding the input length up
196  * to the next full block is always enough, but if there is definitely no
197  * partial data present then it is acceptable to round down. The output
198  * buffer may be NULL if `input_len` is 0.
199  *
200  * Returns the number of output bytes written in `output_len`.
201  *
202  * @param ctx AES-GCM context object.
203  * @param input_len length of input in bytes
204  * @param input input value (may be NULL if input_len is 0)
205  * @param[out] output_len number of output bytes written
206  * @param[out] output resulting output data
207  * @return Error status; OK if no errors
208  */
210 status_t aes_gcm_update_encrypted_data(aes_gcm_context_t *ctx,
211  const size_t input_len,
212  const uint8_t *input, size_t *output_len,
213  uint8_t *output);
214 
215 /**
216  * Finishes an AES-GCM encryption operation.
217  *
218  * Finishes processing the data and computes the tag. If there is partial data
219  * present, `output` must have at least `kAesBlockNumBytes` bytes of space
220  * available. If there is definitely no partial data present, `output` will be
221  * unused and may be NULL.
222  *
223  * If the key is a sideloaded key, it is the caller's responsibility to load
224  * and clear it.
225  *
226  * Returns the number of output bytes written in `output_len`.
227  *
228  * @param ctx AES-GCM context object.
229  * @param tag_len Tag length in 32-bit words
230  * @param[out] tag Output buffer for tag
231  * @param[out] output_len number of output bytes written
232  * @param[out] output resulting output data
233  * @return Error status; OK if no errors
234  */
236 status_t aes_gcm_encrypt_final(aes_gcm_context_t *ctx, size_t tag_len,
237  uint32_t *tag, size_t *output_len,
238  uint8_t *output);
239 
240 /**
241  * Starts an AES-GCM authenticated decryption operation.
242  *
243  * Populates the `ctx` parameter with initial values.
244  *
245  * If the key is a sideloaded key, it is the caller's responsibility to load
246  * and clear it.
247  *
248  * Typical usage looks like this (the `update_encrypted_data` and `update_aad`
249  * calls cannot be interleaved with each other; you must pass all the
250  * associated data before adding encrypted data):
251  * aes_gcm_decrypt_init(...)
252  * aes_gcm_update_aad(...) // call 0 or more times
253  * aes_gcm_update_encrypted_data(...) // call 0 or more times
254  * aes_gcm_encrypt_final(...)
255  *
256  * @param key AES key
257  * @param iv_len length of IV in 32-bit words
258  * @param iv IV value (may be NULL if iv_len is 0)
259  * @param[out] ctx AES-GCM context object.
260  * @return Error status; OK if no errors
261  */
263 status_t aes_gcm_decrypt_init(const aes_key_t key, const size_t iv_len,
264  const uint32_t *iv, aes_gcm_context_t *ctx);
265 
266 /**
267  * Finishes an AES-GCM decryption operation.
268  *
269  * If the key is a sideloaded key, it is the caller's responsibility to load
270  * and clear it.
271  *
272  * Finishes processing the data and computes the tag, then compares it to the
273  * actual tag. If there is partial data present, `output` must have at least
274  * `kAesBlockNumBytes` bytes of space available. If there is definitely no
275  * partial data present, `output` will be unused and may be NULL.
276  *
277  * Returns the number of output bytes written in `output_len`.
278  *
279  * If authentication fails, this function will return `kHardenedBoolFalse` for
280  * the `success` output parameter, and the plaintext should be ignored. Note
281  * the distinction between the `success` output parameter and the return value
282  * (type `status_t`): the return value indicates whether there was an
283  * internal error while processing the function, and `success` indicates
284  * whether the authentication check passed. If the return value is anything
285  * other than OK, all output from this function should be discarded, including
286  * `success`.
287  *
288  * @param ctx AES-GCM context object.
289  * @param tag_len Tag length in 32-bit words
290  * @param[out] tag Output buffer for tag
291  * @param[out] output_len number of output bytes written
292  * @param[out] output resulting output data
293  * @param[out] success True if authentication was successful, otherwise false
294  * @return Error status; OK if no errors
295  */
297 status_t aes_gcm_decrypt_final(aes_gcm_context_t *ctx, size_t tag_len,
298  const uint32_t *tag, size_t *output_len,
299  uint8_t *output, hardened_bool_t *success);
300 
301 #ifdef __cplusplus
302 } // extern "C"
303 #endif // __cplusplus
304 
305 #endif // OPENTITAN_SW_DEVICE_LIB_CRYPTO_IMPL_AES_GCM_AES_GCM_H_