Software APIs
aes_entropy_test.c
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 #include "hw/ip/aes/model/aes_modes.h"
10 #include "sw/device/lib/testing/aes_testutils.h"
11 #include "sw/device/lib/testing/test_framework/check.h"
13 
14 #define TIMEOUT (1000 * 1000)
15 
16 // The mask share, used to mask kKey. Note that the masking should not be done
17 // manually. Software is expected to get the key in two shares right from the
18 // beginning.
19 static const uint8_t kKeyShare1[] = {
20  0x0f, 0x1f, 0x2f, 0x3f, 0x4f, 0x5f, 0x6f, 0x7f, 0x8f, 0x9f, 0xaf,
21  0xbf, 0xcf, 0xdf, 0xef, 0xff, 0x0a, 0x1a, 0x2a, 0x3a, 0x4a, 0x5a,
22  0x6a, 0x7a, 0x8a, 0x9a, 0xaa, 0xba, 0xca, 0xda, 0xea, 0xfa,
23 };
24 
25 OTTF_DEFINE_TEST_CONFIG();
26 
27 status_t execute_test(dif_aes_t *aes) {
28  // Mask the key. Note that this should not be done manually. Software is
29  // expected to get the key in two shares right from the beginning.
30  uint8_t key_share0[sizeof(kAesModesKey256)];
31  for (int i = 0; i < sizeof(kAesModesKey256); ++i) {
32  key_share0[i] = kAesModesKey256[i] ^ kKeyShare1[i];
33  }
34 
35  // "Convert" key share byte arrays to `dif_aes_key_share_t`.
37  memcpy(key.share0, key_share0, sizeof(key.share0));
38  memcpy(key.share1, kKeyShare1, sizeof(key.share1));
39 
40  // "Convert" iv byte arrays to `dif_aes_iv_t`.
41  dif_aes_iv_t iv;
42  memcpy(iv.iv, kAesModesIvCbc, sizeof(iv.iv));
43 
44  // Setup CBC encryption transaction.
45  dif_aes_transaction_t transaction = {
46  .operation = kDifAesOperationEncrypt,
47  .mode = kDifAesModeCbc,
48  .key_len = kDifAesKey256,
49  .key_provider = kDifAesKeySoftwareProvided,
50  .mask_reseeding = kDifAesReseedPerBlock,
51  .manual_operation = kDifAesManualOperationManual,
52  .reseed_on_key_change = false,
53  .ctrl_aux_lock = false,
54  };
55 
56  // Write the initial key share, IV and data in CSRs (known combinations).
57  CHECK_DIF_OK(dif_aes_start(aes, &transaction, &key, &iv));
58  dif_aes_data_t in_data_plain;
59  memcpy(in_data_plain.data, kAesModesPlainText, sizeof(in_data_plain.data));
60  AES_TESTUTILS_WAIT_FOR_STATUS(aes, kDifAesStatusInputReady, true, TIMEOUT);
61  CHECK_DIF_OK(dif_aes_load_data(aes, in_data_plain));
62 
63  // Write the PRNG_RESEED bit to reseed the internal state of the PRNG.
64  CHECK_DIF_OK(dif_aes_trigger(aes, kDifAesTriggerPrngReseed));
65 
66  // Trigger the AES operation to run and wait for it to complete.
67  CHECK_DIF_OK(dif_aes_trigger(aes, kDifAesTriggerStart));
68  AES_TESTUTILS_WAIT_FOR_STATUS(aes, kDifAesStatusOutputValid, true, TIMEOUT);
69 
70  // Check the ciphertext against the expected value.
71  dif_aes_data_t out_data;
72  CHECK_DIF_OK(dif_aes_read_output(aes, &out_data));
73  CHECK_ARRAYS_EQ((uint8_t *)out_data.data, kAesModesCipherTextCbc256,
74  sizeof(out_data.data));
75 
76  // Write the KEY_IV_DATA_IN_CLEAR and DATA_OUT_CLEAR trigger bits to 1 and
77  // wait for it to complete by polling the status idle bit.
78  CHECK_DIF_OK(dif_aes_trigger(aes, kDifAesTriggerDataOutClear));
80  AES_TESTUTILS_WAIT_FOR_STATUS(aes, kDifAesStatusIdle, true, TIMEOUT);
81 
82  // Read back the data out CSRs - they should all read garbage values.
83  CHECK(dif_aes_read_output(aes, &out_data) == kDifError);
84  CHECK(!aes_testutils_get_status(aes, kDifAesStatusOutputValid));
85 
86  // Assertion check verifies that the internal states (data_in, key share and
87  // IV are also garbage, i.e. different from the originally written values.
88  CHECK_DIF_OK(dif_aes_read_iv(aes, &iv));
89  CHECK_ARRAYS_NE((uint8_t *)iv.iv, kAesModesIvCbc, sizeof(kAesModesIvCbc));
90 
91  CHECK_DIF_OK(dif_aes_end(aes));
92 
93  return OK_STATUS();
94 }
95 
96 bool test_main(void) {
97  dif_aes_t aes;
98 
99  // Initialise AES.
100  CHECK_DIF_OK(dif_aes_init_from_dt(kDtAes, &aes));
101  CHECK_DIF_OK(dif_aes_reset(&aes));
102 
103  return status_ok(execute_test(&aes));
104 }