Software APIs
dif_aes.h
Go to the documentation of this file.
1 // Copyright lowRISC contributors.
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_DIF_DIF_AES_H_
6 #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_AES_H_
7 
8 /**
9  * @file
10  * @brief <a href="/hw/ip/aes/doc/">AES</a> Device Interface Functions
11  */
12 
13 #include <stdbool.h>
14 #include <stdint.h>
15 
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif // __cplusplus
22 
23 /**
24  * This API assumes transactional nature of work, where the peripheral is
25  * configured once per message (data consisting of 1..N 128-bit blocks), and
26  * then "de-initialised" when this message has been fully encrypted/decrypted.
27  *
28  * The peripheral is configured through one of the cipher mode "start"
29  * functions:
30  * `dif_aes_start_ecb`, `dif_aes_start_cbc`, ... .
31  *
32  * Then the encryption/decryption data is fed one 128-bit block at the
33  * time through `dif_aes_load_data` function. The cipher mode operation details
34  * are described in the description of above mentioned "start" functions. When
35  * configured in "automatic" operation mode, every "load data" call, will
36  * trigger encryption/decryption. This is not true when in "manual" operation
37  * mode, where encryption/decryption is triggered by explicitly setting the
38  * `aes.TRIGGER.START` flag through `dif_aes_trigger` call.
39  *
40  * When an entire requested message has been processed the internal state of
41  * AES registers must be securely cleared, by calling `dif_aes_end`.
42  *
43  * Please see the following documentation for further information:
44  * https://docs.opentitan.org/hw/ip/aes/doc/
45  * https://csrc.nist.gov/csrc/media/publications/fips/197/final/documents/fips-197.pdf
46  * https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf
47  */
48 
49 /**
50  * A typed representation of the AES key share.
51  *
52  * Two part masked AES key, where XOR operation of these two parts results in
53  * the actual key.
54  */
55 typedef struct dif_aes_key_share {
56  /**
57  * One share of the key that when XORed with `share1` results in the actual
58  * key.
59  */
60  uint32_t share0[8];
61  /**
62  * One share of the key that when XORed with `share0` results in the actual
63  * key.
64  */
65  uint32_t share1[8];
67 
68 /**
69  * A typed representation of the AES Initialisation Vector (IV).
70  */
71 typedef struct dif_aes_iv {
72  uint32_t iv[4];
73 } dif_aes_iv_t;
74 
75 /**
76  * A typed representation of the AES data.
77  */
78 typedef struct dif_aes_data {
79  uint32_t data[4];
81 
82 /**
83  * AES key length in bits.
84  */
85 typedef enum dif_aes_key_length {
86  /**
87  * 128 bit wide AES key.
88  */
90  /**
91  * 192 bit wide AES key.
92  */
94  /**
95  * 256 bit wide AES key.
96  */
99 
100 /**
101  * AES mode.
102  */
103 typedef enum dif_aes_mode {
104  /**
105  * AES encryption mode.
106  */
108  /**
109  * AES decryption mode.
110  */
113 
114 /**
115  * AES operation.
116  */
117 typedef enum dif_aes_operation {
118  /**
119  * AES operates in automatic mode - which means that the encryption/decryption
120  * is automatically triggered on every successful `dif_aes_*_load_data()`.
121  */
123  /**
124  * AES operates in manual mode - which means that the encryption/decryption
125  * is manually triggered by `dif_aes_trigger(kDifAesTriggerStart)`.
126  */
129 
130 /**
131  * AES masking.
132  *
133  * NOTE:
134  * This should only be used for development purpose (SCA), and expected to be
135  * removed before the production version.
136  */
137 typedef enum dif_aes_masking {
138  /**
139  * Pseudo-random generator is used for masking.
140  */
142  /**
143  * Completely disables masking by forcing all masks to zero.
144  */
147 
148 /**
149  * Parameters for an AES transaction.
150  */
151 typedef struct dif_aes_transaction {
152  dif_aes_key_length_t key_len;
153  dif_aes_mode_t mode;
154  dif_aes_operation_t operation;
155  dif_aes_masking_t masking;
157 
158 /**
159  * An AES alert type.
160  */
161 typedef enum dif_aes_alert {
162  /**
163  * Fatal alert conditions include i) storage errors in the Control Register,
164  * and ii) if any internal FSM enters an invalid state.
165  */
167  /**
168  * Recoverable alert conditions include update errors in the Control Register.
169  */
172 
173 /**
174  * Hardware instantiation parameters for AES.
175  *
176  * This struct describes information about the underlying hardware that is
177  * not determined until the hardware design is used as part of a top-level
178  * design.
179  */
180 typedef struct dif_aes_params {
181  /**
182  * The base address for the AES hardware registers.
183  */
186 
187 /**
188  * A handle to AES.
189  *
190  * This type should be treated as opaque by users.
191  */
192 typedef struct dif_aes {
193  dif_aes_params_t params;
194 } dif_aes_t;
195 
196 /**
197  * The result of a AES operation.
198  */
199 typedef enum dif_aes_result {
200  /**
201  * Indicates that the operation succeeded.
202  */
204  /**
205  * Indicates some unspecified failure.
206  */
208  /**
209  * Indicates that some parameter passed into a function failed a
210  * precondition.
211  *
212  * When this value is returned, no hardware operations occurred.
213  */
216 
217 /**
218  * Creates a new handle for AES.
219  *
220  * This function does not actuate the hardware.
221  *
222  * @param params Hardware instantiation parameters.
223  * @param[out] aes Out param for the initialised handle.
224  * @return The result of the operation.
225  */
228 
229 /**
230  * The result of a AES reset operation.
231  */
232 typedef enum dif_aes_reset_result {
233  /**
234  * Indicates that the operation succeeded.
235  */
237  /**
238  * Indicates some unspecified failure.
239  */
241  /**
242  * Indicates that some parameter passed into a function failed a
243  * precondition.
244  *
245  * When this value is returned, no hardware operations occurred.
246  */
248  /**
249  * Device is busy, and cannot perform the requested operation.
250  */
253 
254 /**
255  * Resets an instance of AES.
256  *
257  * Clears the internal state along with the interface registers.
258  *
259  * @param aes AES state data.
260  * @return The result of the operation.
261  */
263 dif_aes_reset_result_t dif_aes_reset(const dif_aes_t *aes);
264 
265 /**
266  * The result of a AES start operation.
267  */
268 typedef enum dif_aes_start_result {
269  /**
270  * Indicates that the operation succeeded.
271  */
273  /**
274  * Indicates some unspecified failure.
275  */
277  /**
278  * Indicates that some parameter passed into a function failed a
279  * precondition.
280  *
281  * When this value is returned, no hardware operations occurred.
282  */
284  /**
285  * Device is busy, and cannot perform the requested operation.
286  */
289 
290 /**
291  * Begins an AES transaction in ECB mode.
292  *
293  * In ECB cipher mode the key must be changed for every new block of data. This
294  * is the only secure way to use ECB cipher mode.
295  *
296  * Each call to this function should be sequenced with a call to
297  * `dif_aes_end()`.
298  *
299  * Note: it is discouraged to use this cipher mode, due to inpractical amount
300  * of different keys required to encrypt/decrypt multi-block messages.
301  *
302  * The peripheral must be in IDLE state for this operation to take
303  * effect, and will return `kDifAesStartBusy` if this condition is not
304  * met.
305  *
306  * @param aes AES state data.
307  * @param transaction Configuration data.
308  * @return The result of the operation.
309  */
311 dif_aes_start_result_t dif_aes_start_ecb(
312  const dif_aes_t *aes, const dif_aes_transaction_t *transaction,
313  dif_aes_key_share_t key);
314 
315 /**
316  * Begins an AES transaction in CBC mode.
317  *
318  * In CBC cipher mode, the same key can be used for all messages, however
319  * new Initialisation Vector (IV) must be generated for any new message. The
320  * following condition must be true:
321  * The IV must be unpredictable (it must not be possible to predict the IV
322  * that will be associated to the plaintext in advance of the generation of
323  * the IV).
324  *
325  * With key length less than 256 bits, the excess portion of the `key` can be
326  * written with any data (preferably random).
327  *
328  * The peripheral must be in IDLE state for this operation to take effect, and
329  * will return `kDifAesStartBusy` if this condition is not met.
330  *
331  * @param aes AES state data.
332  * @param transaction Configuration data.
333  * @param key Masked AES key.
334  * @param iv AES Initialisation Vector.
335  * @return The result of the operation.
336  */
338 dif_aes_start_result_t dif_aes_start_cbc(
339  const dif_aes_t *aes, const dif_aes_transaction_t *transaction,
341 
342 /**
343  * Begins an AES transaction in CTR mode.
344  *
345  * In CTR cipher mode, the same key can be used for all messages, if the
346  * following condition is true:
347  * CTR mode requires a unique counter block for each plaintext block that
348  * is ever encrypted under a given key, across all messages.
349  *
350  * With key length less than 256 bits, the excess portion of the `key` can be
351  * written with any data (preferably random).
352  *
353  * The peripheral must be in IDLE state for this operation to take effect, and
354  * will return `kDifAesStartBusy` if this condition is not met.
355  *
356  * @param aes AES state data.
357  * @param transaction Configuration data.
358  * @param key Masked AES key.
359  * @param iv AES Initial Counter Value.
360  * @return The result of the operation.
361  */
363 dif_aes_start_result_t dif_aes_start_ctr(
364  const dif_aes_t *aes, const dif_aes_transaction_t *transaction,
366 
367 /**
368  * The result of an AES end operation.
369  */
370 typedef enum dif_aes_end_result {
371  /**
372  * Indicates that the operation succeeded.
373  */
375  /**
376  * Indicates some unspecified failure.
377  */
379  /**
380  * Indicates that some parameter passed into a function failed a
381  * precondition.
382  *
383  * When this value is returned, no hardware operations occurred.
384  */
386  /**
387  * Device is busy, and cannot perform the requested operation.
388  */
391 
392 /**
393  * Ends an AES transaction.
394  *
395  * This function must be called at the end of every `dif_aes_<mode>_start`
396  * operation.
397  *
398  * The peripheral must be in IDLE state for this operation to take effect, and
399  * will return `kDifAesEndBusy` if this condition is not met.
400  *
401  * @param aes AES state data.
402  * @return The result of the operation.
403  */
405 dif_aes_end_result_t dif_aes_end(const dif_aes_t *aes);
406 
407 /**
408  * The result of an AES load data operation.
409  */
411  /**
412  * Indicates that the operation succeeded.
413  */
415  /**
416  * Indicates some unspecified failure.
417  */
419  /**
420  * Indicates that some parameter passed into a function failed a
421  * precondition.
422  *
423  * When this value is returned, no hardware operations occurred.
424  */
426  /**
427  * Device is busy, and cannot perform the requested operation.
428  */
431 
432 /**
433  * Loads AES Input Data.
434  *
435  * This function will trigger encryption/decryption when configured in
436  * the automatic operation mode.
437  *
438  * The peripheral must be able to accept the input (INPUT_READY set), and
439  * will return `kDifAesLoadDataBusy` if this condition is not met.
440  *
441  * @param aes AES state data.
442  * @param data AES Input Data.
443  * @return The result of the operation.
444  */
446 dif_aes_load_data_result_t dif_aes_load_data(const dif_aes_t *aes,
447  const dif_aes_data_t data);
448 
449 /**
450  * The result of an AES data read operation.
451  */
453  /**
454  * Indicates that the operation succeeded.
455  */
457  /**
458  * Indicates some unspecified failure.
459  */
461  /**
462  * Indicates that some parameter passed into a function failed a
463  * precondition.
464  *
465  * When this value is returned, no hardware operations occurred.
466  */
468  /**
469  * The AES unit has no valid output.
470  */
473 
474 /**
475  * Reads AES Output Data.
476  *
477  * The peripheral must have finished previous encryption/decryption operation,
478  * and have valid data in the output registers (OUTPUT_VALID set), and will
479  * return `kDifAesReadOutputInvalid` if this condition is not met.
480  *
481  * @param aes AES state data.
482  * @param data AES Output Data.
483  * @return The result of the operation.
484  */
486 dif_aes_read_output_result_t dif_aes_read_output(const dif_aes_t *aes,
487  dif_aes_data_t *data);
488 
489 /**
490  * AES Trigger flags.
491  */
492 typedef enum dif_aes_trigger {
493  /**
494  * Trigger encrypt/decrypt.
495  */
497  /**
498  * Clear key, Initialisation Vector/Initial Counter Value and input data.
499  */
501  /**
502  * Clear Output Data registers.
503  */
505  /**
506  * Perform reseed of the internal state.
507  */
510 
511 /**
512  * Triggers one of `dif_aes_trigger_t` operations.
513  *
514  * All the triggers are applicable to both (automatic and manual) modes, with
515  * the exception of `kDifAesTriggerStart`, which is ignored in automatic mode.
516  *
517  * @param aes AES state data.
518  * @param trigger AES trigger.
519  * @return The result of the operation.
520  */
523  dif_aes_trigger_t trigger);
524 
525 /**
526  * AES Status flags.
527  */
528 typedef enum dif_aes_status {
529  /**
530  * Device is idle.
531  */
533  /**
534  * Device has stalled (only relevant in automatic
535  * operation mode). Output data overwrite
536  * protection.
537  */
539  /**
540  * Output data has been overwritten by the AES unit before the processor
541  * could fully read it. This bit is "sticky" for the entire duration of
542  * the current transaction.
543  */
545  /**
546  * Device output is valid/ready. Denotes a
547  * successful encrypt or decrypt operation.
548  */
550  /**
551  * Device Input Data registers can be written to
552  * (ready to accept new input data).
553  */
555  /**
556  * Fatal alert conditions include i) storage errors in the Control Register,
557  * and ii) if any internal FSM enters an invalid state.
558  */
560  /**
561  * Recoverable alert conditions include update errors in the Control Register.
562  */
565 
566 /**
567  * Queries the AES status flags.
568  *
569  * @param aes AES state data.
570  * @param flag Status flag to query.
571  * @param set Flag state (set/unset).
572  * @return The result of the operation.
573  */
575 dif_aes_result_t dif_aes_get_status(const dif_aes_t *aes, dif_aes_status_t flag,
576  bool *set);
577 
578 /**
579  * Forces a particular alert, causing it to be serviced as if hardware had
580  * asserted it.
581  *
582  * @param aes AES state data.
583  * @param alert An alert type.
584  * @return The result of the operation.
585  */
588  dif_aes_alert_t alert);
589 
590 #ifdef __cplusplus
591 } // extern "C"
592 #endif // __cplusplus
593 
594 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_AES_H_