Software APIs
aes.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 #ifndef OPENTITAN_SW_DEVICE_LIB_CRYPTO_DRIVERS_AES_H_
5 #define OPENTITAN_SW_DEVICE_LIB_CRYPTO_DRIVERS_AES_H_
6 
9 #include "sw/device/lib/base/status.h"
10 
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14 
15 enum {
16  /** Number of bits in an AES cipher block. */
17  kAesBlockNumBits = 128,
18  /** Number of bytes in an AES cipher block. */
19  kAesBlockNumBytes = kAesBlockNumBits / 8,
20  /** Number of words in an AES cipher block. */
21  kAesBlockNumWords = kAesBlockNumBytes / sizeof(uint32_t),
22 };
23 
24 /**
25  * An AES block, which may represent plaintext or ciphertext.
26  */
27 typedef struct aes_block {
28  uint32_t data[kAesBlockNumWords];
29 } aes_block_t;
30 
31 /**
32  * A cipher mode supported by the AES hardware.
33  *
34  * Values of this enum must match the block cipher mode enum from the top-level
35  * API.
36  */
37 typedef enum aes_cipher_mode {
38  kAesCipherModeEcb = 0x533,
39  kAesCipherModeCbc = 0x45d,
40  kAesCipherModeCfb = 0xcd2,
41  kAesCipherModeOfb = 0x39a,
42  kAesCipherModeCtr = 0xd2c,
43 } aes_cipher_mode_t;
44 
45 /**
46  * Represents an AES key.
47  *
48  * The key may be provided by software as two shares, or it may be a sideloaded
49  * key that is produced by the keymgr and not visible to software.
50  */
51 typedef struct aes_key {
52  /**
53  * Block cipher mode for which the key is intended.
54  */
55  aes_cipher_mode_t mode;
56 
57  /**
58  * Whether the key is sideloaded.
59  */
61 
62  /**
63  * The length of the key (in 32-bit words).
64  */
65  size_t key_len;
66 
67  /**
68  * The key, split into two shares. The actual key will be formed by
69  * XORing both keys together.
70  *
71  * Neither entry may be null. If a non-shared key is desired, one of
72  * the two pointers should be pointed to an array of zero-valued words
73  * of sufficient length.
74  */
75  const uint32_t *key_shares[2];
76 } aes_key_t;
77 
78 /**
79  * Prepares the AES hardware to perform an encryption operation.
80  *
81  * If `key.sideload` is true, then this routine does not load the key; the
82  * caller must separately call keymgr to write the key into the AES block before
83  * calling `aes_update`.
84  *
85  * If the selected mode requires an IV, then `iv` must not be null. Otherwise
86  * (e.g. for ECB mode), `iv` is ignored and may be null.
87  *
88  * @param key Encryption key.
89  * @param iv IV to use for non-ECB modes, 128 bits.
90  * @return The result of the operation.
91  */
93 status_t aes_encrypt_begin(const aes_key_t key, const aes_block_t *iv);
94 
95 /**
96  * Prepares the AES hardware to perform a decryption operation.
97  *
98  * If `key.sideload` is true, then this routine does not load the key; the
99  * caller must separately call keymgr to write the key into the AES block before
100  * calling `aes_update`.
101  *
102  * If the selected mode requires an IV, then `iv` must not be null. Otherwise
103  * (e.g. for ECB mode), `iv` is ignored and may be null.
104  *
105  * @param key Encryption key.
106  * @param iv IV to use for non-ECB modes, 128 bits.
107  * @return The result of the operation.
108  */
110 status_t aes_decrypt_begin(const aes_key_t key, const aes_block_t *iv);
111 
112 /**
113  * Advances the AES state by a single block.
114  *
115  * The AES hardware does not simply perform a single synchronous block
116  * operation; there is a delay as a block makes it way through the hardware;
117  * outputs are delayed one input from when it is fed into the hardware.
118  *
119  * Therefore, this function works as follows:
120  * 1. The contents of `src` are fed into the hardware (unless it is null, in
121  * which case this step is skipped).
122  * 2. The contents of `dest` are filled with the hardware's output (again,
123  * unless it is null). `dest` may overlap with `src`.
124  *
125  * Operation of the driver will look something like this:
126  * ```
127  * aes_encrypt_begin(...);
128  * aes_update(NULL, input0);
129  * aes_update(output0, input1);
130  * // ...
131  * aes_update(output(N-1), inputN);
132  * aes_update(outputN, NULL);
133  * aes_end(...);
134  * ```
135  *
136  * @param dest The output block.
137  * @param src The input block.
138  * @return The result of the operation.
139  */
141 status_t aes_update(aes_block_t *dest, const aes_block_t *src);
142 
143 /**
144  * Completes an AES session by clearing control settings and key material.
145  *
146  * If `iv` is non-null, reads back the final IV block and returns it to the
147  * caller.
148  *
149  * @param[out] iv Buffer for the final IV (may be null).
150  * @return The result of the operation.
151  */
153 status_t aes_end(aes_block_t *iv);
154 
155 #ifdef __cplusplus
156 }
157 #endif
158 
159 #endif // OPENTITAN_SW_DEVICE_LIB_CRYPTO_DRIVERS_AES_H_