Software APIs
sw
device
lib
dif
dif_aes.h
Go to the documentation of this file.
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_DIF_DIF_AES_H_
6
#define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_AES_H_
7
8
#include <
stdbool.h
>
9
#include <
stdint.h
>
10
11
#include "
sw/device/lib/base/macros.h
"
12
#include "
sw/device/lib/base/mmio.h
"
13
#include "
sw/device/lib/dif/dif_base.h
"
14
15
#include "
sw/device/lib/dif/autogen/dif_aes_autogen.h
"
16
17
#ifdef __cplusplus
18
extern
"C"
{
19
#endif
// __cplusplus
20
21
/**
22
*
23
* @file
24
* @brief <a href="/hw/ip/aes/doc/">AES</a> Device Interface Functions
25
*
26
* This API assumes transactional nature of work, where the peripheral is
27
* configured once per message (data consisting of 1..N 128-bit blocks), and
28
* then "de-initialised" when this message has been fully encrypted/decrypted.
29
*
30
* The peripheral is configured through one of the cipher mode "start"
31
* functions:
32
* `dif_aes_start_ecb`, `dif_aes_start_cbc`, ... .
33
*
34
* Then the encryption/decryption data is fed one 128-bit block at the
35
* time through `dif_aes_load_data` function. The cipher mode operation details
36
* are described in the description of above mentioned "start" functions. When
37
* configured in "automatic" operation mode, every "load data" call, will
38
* trigger encryption/decryption. This is not true when in "manual" operation
39
* mode, where encryption/decryption is triggered by explicitly setting the
40
* `aes.TRIGGER.START` flag through `dif_aes_trigger` call.
41
*
42
* When an entire requested message has been processed the internal state of
43
* AES registers must be securely cleared, by calling `dif_aes_end`.
44
*
45
* Please see the following documentation for further information:
46
* https://docs.opentitan.org/hw/ip/aes/doc/
47
* https://csrc.nist.gov/csrc/media/publications/fips/197/final/documents/fips-197.pdf
48
* https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf
49
*/
50
51
/**
52
* A typed representation of the AES key share.
53
*
54
* Two part masked AES key, where XOR operation of these two parts results in
55
* the actual key.
56
*/
57
typedef
struct
dif_aes_key_share
{
58
/**
59
* One share of the key that when XORed with `share1` results in the actual
60
* key.
61
*/
62
uint32_t
share0
[8];
63
/**
64
* One share of the key that when XORed with `share0` results in the actual
65
* key.
66
*/
67
uint32_t
share1
[8];
68
}
dif_aes_key_share_t
;
69
70
/**
71
* A typed representation of the AES Initialisation Vector (IV).
72
*/
73
typedef
struct
dif_aes_iv
{
74
uint32_t iv[4];
75
}
dif_aes_iv_t
;
76
77
/**
78
* A typed representation of the AES data.
79
*/
80
typedef
struct
dif_aes_data
{
81
uint32_t data[4];
82
}
dif_aes_data_t
;
83
84
/**
85
* AES operation.
86
*/
87
typedef
enum
dif_aes_operation
{
88
/**
89
* AES encryption.
90
*/
91
kDifAesOperationEncrypt
= 1,
92
/**
93
* AES decryption.
94
*/
95
kDifAesOperationDecrypt
= 2,
96
}
dif_aes_operation_t
;
97
98
/**
99
* AES block cipher mode of operation.
100
*/
101
typedef
enum
dif_aes_mode
{
102
/**
103
* The Electronic Codebook Mode.
104
* In ECB cipher mode the key must be changed for every new block of data.
105
* This is the only secure way to use ECB cipher mode.
106
*
107
* Note: The ECB cipher mode doesn't use the iv parameter of the
108
* `dif_aes_start` function.
109
*
110
* Note: it is discouraged to use this cipher mode, due to impractical amount
111
* of different keys required to encrypt/decrypt multi-block messages.
112
*/
113
kDifAesModeEcb
= 1,
114
115
/**
116
* The Cipher Block Chaining Mode.
117
*
118
* In CBC cipher mode, the same key can be used for all messages, however
119
* new Initialisation Vector (IV) must be generated for any new message. The
120
* following condition must be true:
121
* The IV must be unpredictable (it must not be possible to predict the IV
122
* that will be associated to the plaintext in advance of the generation
123
* of the IV).
124
*
125
* With key length less than 256 bits, the excess portion of the `key` can be
126
* written with any data (preferably random).
127
*/
128
kDifAesModeCbc
= (1 << 1),
129
130
/**
131
* The Cipher Feedback Mode.
132
*
133
* In CFB cipher mode, the same key can be used for all messages, however
134
* new Initialisation Vector (IV) must be generated for any new message. The
135
* following condition must be true:
136
* The IV must be unpredictable (it must not be possible to predict the IV
137
* that will be associated to the plaintext in advance of the generation
138
* of the IV).
139
*
140
* With key length less than 256 bits, the excess portion of the `key` can be
141
* written with any data (preferably random).
142
*/
143
kDifAesModeCfb
= (1 << 2),
144
145
/**
146
* The Output Feedback Mode.
147
*
148
* In OFB cipher mode, the same key can be used for all messages, and the
149
* Initialization Vector (IV) need NOT be unpredictable. The following
150
* conditions must be true:
151
* OFB mode requires a unique initialization vector for every message that
152
* is ever encrypted under a given key, across all messages.
153
*
154
* With key length less than 256 bits, the excess portion of the `key` can be
155
* written with any data (preferably random).
156
*/
157
kDifAesModeOfb
= (1 << 3),
158
159
/**
160
* The Counter Mode.
161
*
162
* In CTR cipher mode, the same key can be used for all messages, if the
163
* following condition is true:
164
* CTR mode requires a unique counter block for each plaintext block that
165
* is ever encrypted under a given key, across all messages.
166
*
167
* With key length less than 256 bits, the excess portion of the `key` can be
168
* written with any data (preferably random).
169
*/
170
kDifAesModeCtr
= (1 << 4),
171
}
dif_aes_mode_t
;
172
173
/**
174
* AES key length in bits.
175
*/
176
typedef
enum
dif_aes_key_length
{
177
/**
178
* 128 bit wide AES key.
179
*/
180
kDifAesKey128
= 1,
181
/**
182
* 192 bit wide AES key.
183
*/
184
kDifAesKey192
= (1 << 1),
185
/**
186
* 256 bit wide AES key.
187
*/
188
kDifAesKey256
= (1 << 2)
189
}
dif_aes_key_length_t
;
190
191
/**
192
* AES manual operation.
193
*/
194
typedef
enum
dif_aes_manual_operation
{
195
/**
196
* AES operates in automatic mode - which means that the encryption/decryption
197
* is automatically triggered on every successful `dif_aes_*_load_data()`.
198
*/
199
kDifAesManualOperationAuto
= 0,
200
/**
201
* AES operates in manual mode - which means that the encryption/decryption
202
* is manually triggered by `dif_aes_trigger(kDifAesTriggerStart)`.
203
*/
204
kDifAesManualOperationManual
,
205
}
dif_aes_manual_operation_t
;
206
207
/**
208
* AES key sideloaded.
209
*
210
* Controls whether the AES uses the key provided by the key manager or
211
* software.
212
*/
213
typedef
enum
dif_aes_key_provider
{
214
/**
215
* The key is provided by software via `dif_aes_key_share_t`.
216
*/
217
kDifAesKeySoftwareProvided
= 0,
218
/**
219
* The key be provided by the key manager.
220
*/
221
kDifAesKeySideload
,
222
}
dif_aes_key_provider_t
;
223
224
/**
225
* AES reseeding rate
226
*
227
* Controls the reseeding rate of the internal pseudo-random number generator
228
* (PRNG) used for masking.
229
*/
230
typedef
enum
dif_aes_mask_reseeding
{
231
/**
232
* The masking PRNG will be reseed every block.
233
*/
234
kDifAesReseedPerBlock
= 1 << 0,
235
/**
236
* The masking PRNG will be reseed every 64 blocks.
237
*/
238
kDifAesReseedPer64Block
= 1 << 1,
239
/**
240
* The masking PRNG will be reseed every 8192 blocks.
241
*/
242
kDifAesReseedPer8kBlock
= 1 << 2,
243
}
dif_aes_mask_reseeding_t
;
244
245
/**
246
* Parameters for an AES transaction.
247
*/
248
typedef
struct
dif_aes_transaction
{
249
dif_aes_operation_t
operation;
250
dif_aes_mode_t
mode;
251
dif_aes_key_length_t
key_len;
252
dif_aes_manual_operation_t
manual_operation;
253
dif_aes_key_provider_t
key_provider;
254
dif_aes_mask_reseeding_t
mask_reseeding;
255
/**
256
* If true the internal pseudo-random number generators used for clearing and
257
* masking will be reseeded every time the key changes.
258
*/
259
bool
reseed_on_key_change
;
260
/**
261
* If true, the internal pseudo-random number generator used for masking is
262
* not advancing leading to constant masks.
263
*
264
* NOTE: This should only be used for development purpose (SCA), and is
265
* expected to be removed for the production version.
266
*/
267
bool
force_masks
;
268
/**
269
* If true `reseed_on_key_change` and `force_masks` will be locked until the
270
* device is reset.
271
*/
272
bool
ctrl_aux_lock
;
273
}
dif_aes_transaction_t
;
274
275
/**
276
* Resets an instance of AES.
277
*
278
* Clears the internal state along with the interface registers.
279
*
280
* @param aes AES state data.
281
* @return The result of the operation.
282
*/
283
OT_WARN_UNUSED_RESULT
284
dif_result_t
dif_aes_reset
(
const
dif_aes_t
*aes);
285
286
/**
287
* Begins an AES transaction in the mode selected by the `transaction->mode`.
288
*
289
* Each call to this function should be sequenced with a call to
290
* `dif_aes_end()`.
291
*
292
* The peripheral must be in IDLE state for this operation to take effect, and
293
* will return `kDifAesBusy` if this condition is not met.
294
*
295
* @param aes AES state data.
296
* @param transaction Configuration data.
297
* @param key Encryption/decryption key when `kDifAesKeySoftwareProvided`, can
298
* be `NULL` otherwise.
299
* @param iv Initialization vector when the mode isn't `kDifAesModeEcb`, can be
300
* `NULL` otherwise.
301
* @return The result of the operation.
302
*/
303
OT_WARN_UNUSED_RESULT
304
dif_result_t
dif_aes_start
(
const
dif_aes_t
*aes,
305
const
dif_aes_transaction_t
*transaction,
306
const
dif_aes_key_share_t
*key,
307
const
dif_aes_iv_t
*iv);
308
/**
309
* Ends an AES transaction.
310
*
311
* This function must be called at the end of every `dif_aes_<mode>_start`
312
* operation.
313
*
314
* The peripheral must be in IDLE state for this operation to take effect, and
315
* will return `kDifAesEndBusy` if this condition is not met.
316
*
317
* @param aes AES state data.
318
* @return The result of the operation.
319
*/
320
OT_WARN_UNUSED_RESULT
321
dif_result_t
dif_aes_end
(
const
dif_aes_t
*aes);
322
323
/**
324
* Loads AES Input Data.
325
*
326
* This function will trigger encryption/decryption when configured in
327
* the automatic operation mode.
328
*
329
* The peripheral must be able to accept the input (INPUT_READY set), and
330
* will return `kDifAesLoadDataBusy` if this condition is not met.
331
*
332
* @param aes AES state data.
333
* @param data AES Input Data.
334
* @return The result of the operation.
335
*/
336
OT_WARN_UNUSED_RESULT
337
dif_result_t
dif_aes_load_data
(
const
dif_aes_t
*aes,
const
dif_aes_data_t
data);
338
339
/**
340
* Reads AES Output Data.
341
*
342
* The peripheral must have finished previous encryption/decryption operation,
343
* and have valid data in the output registers (OUTPUT_VALID set), and will
344
* return `kDifAesReadOutputInvalid` if this condition is not met.
345
*
346
* @param aes AES state data.
347
* @param data AES Output Data.
348
* @return The result of the operation.
349
*/
350
OT_WARN_UNUSED_RESULT
351
dif_result_t
dif_aes_read_output
(
const
dif_aes_t
*aes,
dif_aes_data_t
*data);
352
353
/**
354
* Process a stream of data containing the plain text and output a stream of
355
* data with the cipher text.
356
*
357
* This function should be used when performance is desired. It requires the
358
* automatic operation mode activated.
359
*
360
* The peripheral must be able to accept the input (INPUT_READY set), and
361
* will return `kDifAesLoadDataBusy` if this condition is not met.
362
*
363
* @param aes AES handle.
364
* @param plain_text AES Input Data.
365
* @param cipher_text AES Output Data.
366
* @param block_amount The amount of blocks to be encrypted.
367
* @return The result of the operation.
368
*/
369
OT_WARN_UNUSED_RESULT
370
dif_result_t
dif_aes_process_data
(
const
dif_aes_t
*aes,
371
const
dif_aes_data_t
*plain_text,
372
dif_aes_data_t
*cipher_text,
373
size_t
block_amount);
374
375
/**
376
* AES Trigger flags.
377
*/
378
typedef
enum
dif_aes_trigger
{
379
/**
380
* Trigger encrypt/decrypt.
381
*/
382
kDifAesTriggerStart
= 0,
383
/**
384
* Clear key, Initialisation Vector/Initial Counter Value and input data.
385
*/
386
kDifAesTriggerKeyIvDataInClear
,
387
/**
388
* Clear Output Data registers.
389
*/
390
kDifAesTriggerDataOutClear
,
391
/**
392
* Perform reseed of the internal state.
393
*/
394
kDifAesTriggerPrngReseed
,
395
}
dif_aes_trigger_t
;
396
397
/**
398
* Triggers one of `dif_aes_trigger_t` operations.
399
*
400
* All the triggers are applicable to both (automatic and manual) modes, with
401
* the exception of `kDifAesTriggerStart`, which is ignored in automatic mode.
402
*
403
* @param aes AES state data.
404
* @param trigger AES trigger.
405
* @return The result of the operation.
406
*/
407
OT_WARN_UNUSED_RESULT
408
dif_result_t
dif_aes_trigger
(
const
dif_aes_t
*aes,
dif_aes_trigger_t
trigger);
409
410
/**
411
* AES Status flags.
412
*/
413
typedef
enum
dif_aes_status
{
414
/**
415
* Device is idle.
416
*/
417
kDifAesStatusIdle
= 0,
418
/**
419
* Device has stalled (only relevant in automatic
420
* operation mode). Output data overwrite
421
* protection.
422
*/
423
kDifAesStatusStall
,
424
/**
425
* Output data has been overwritten by the AES unit before the processor
426
* could fully read it. This bit is "sticky" for the entire duration of
427
* the current transaction.
428
*/
429
kDifAesStatusOutputLost
,
430
/**
431
* Device output is valid/ready. Denotes a
432
* successful encrypt or decrypt operation.
433
*/
434
kDifAesStatusOutputValid
,
435
/**
436
* Device Input Data registers can be written to
437
* (ready to accept new input data).
438
*/
439
kDifAesStatusInputReady
,
440
/**
441
* Fatal alert conditions include i) storage errors in the Control Register,
442
* and ii) if any internal FSM enters an invalid state.
443
*/
444
kDifAesStatusAlertFatalFault
,
445
/**
446
* Recoverable alert conditions include update errors in the Control Register.
447
*/
448
kDifAesStatusAlertRecovCtrlUpdateErr
,
449
}
dif_aes_status_t
;
450
451
/**
452
* Queries the AES status flags.
453
*
454
* @param aes AES state data.
455
* @param flag Status flag to query.
456
* @param[out] set Flag state (set/unset).
457
* @return The result of the operation.
458
*/
459
OT_WARN_UNUSED_RESULT
460
dif_result_t
dif_aes_get_status
(
const
dif_aes_t
*aes,
dif_aes_status_t
flag,
461
bool
*set);
462
463
/**
464
* Read the current initialization vector from its register.
465
*
466
* @param aes AES handle.
467
* @param iv The pointer to receive the initialization vector.
468
* @return The result of the operation.
469
*/
470
OT_WARN_UNUSED_RESULT
471
dif_result_t
dif_aes_read_iv
(
const
dif_aes_t
*aes,
dif_aes_iv_t
*iv);
472
473
#ifdef __cplusplus
474
}
// extern "C"
475
#endif
// __cplusplus
476
477
#endif
// OPENTITAN_SW_DEVICE_LIB_DIF_DIF_AES_H_
Return to
OpenTitan Documentation