Software APIs
aes_serial.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 
8 #include "sw/device/lib/testing/test_framework/check.h"
10 #include "sw/device/lib/testing/test_framework/ottf_test_config.h"
11 #include "sw/device/sca/lib/aes.h"
12 #include "sw/device/sca/lib/prng.h"
14 #include "sw/device/tests/penetrationtests/firmware/lib/pentest_lib.h"
15 
16 #ifndef OPENTITAN_IS_ENGLISHBREAKFAST
17 #include "sw/device/lib/testing/aes_testutils.h"
18 #endif
19 
21 
22 /**
23  * OpenTitan program for AES side-channel analysis.
24  *
25  * This program implements the following simple serial commands:
26  * - Set key ('k')*,
27  * - Encrypt ('p')*,
28  * - Version ('v')+,
29  * - Seed PRNG ('s')+,
30  * - Batch encrypt ('b')*,
31  * - FvsR batch fixed key set ('f')*,
32  * - FvsR batch generate ('g')*,
33  * - FvsR batch encrypt and generate ('e')*,
34  * - Batch encrypt alternative routine ('a')*,
35  * - Batch encrypt alternative routine, initial plaintext input ('i')*.
36  * - Set default values for AES-based data generation ('d')*,
37  * Commands marked with * are implemented in this file. Those marked with + are
38  * implemented in the simple serial library. Encryption is done in AES-ECB-128
39  * mode. See https://wiki.newae.com/SimpleSerial for details on the protocol.
40  *
41  * Data for running batch capture is generated according to:
42  * [DTR] Test Vector Leakage Assessment (TVLA) Derived Test Requirements (DTR)
43  * with AES
44  */
45 
46 OTTF_DEFINE_TEST_CONFIG();
47 
48 enum {
49  kAesKeyLengthMax = 32,
50  kAesKeyLength = 16,
51  kAesTextLength = 16,
52  /**
53  * Number of cycles (at `kClockFreqCpuHz`) that Ibex should sleep to minimize
54  * noise during AES operations. Caution: This number should be chosen to
55  * provide enough time. Otherwise, Ibex might wake up while AES is still busy
56  * and disturb the capture. Currently, we use a start trigger delay of 320
57  * clock cycles and the scope captures 60 clock cycles at kClockFreqCpuHz.
58  */
59  kIbexAesSleepCycles = 680,
60  /**
61  * The maximum number of encryptions to do per batch. The ChipWhisperer Husky
62  * scope determines how many encryptions (capture segments) it wants to record
63  * per batch based on the number of samples per segment. As the plaintexts
64  * and keys are generated in advance for fixed-vs-random batch captures, we
65  * need to make sure the corresponding buffers are sufficiently large. Note
66  * that on both CW305 and CW310, the main SRAM has a size of 128 kBytes. So it
67  * should be fine to allocate space for 256 segments (2 * 16 Bytes * 256 = 8
68  * kBytes).
69  */
70  kNumBatchOpsMax = 256,
71  /**
72  * Max number of encryptions that can be captured before we rewrite the key to
73  * reset the internal block counter. Otherwise, the AES peripheral might
74  * trigger the reseeding of the internal masking PRNG which disturbs SCA
75  * measurements.
76  */
77  kBlockCtrMax = 8191,
78 };
79 
80 /**
81  * An array of keys to be used in a batch.
82  */
83 uint8_t batch_keys[kNumBatchOpsMax][kAesKeyLength];
84 
85 /**
86  * An array of plaintexts to be used in a batch.
87  */
88 uint8_t batch_plaintexts[kNumBatchOpsMax][kAesTextLength];
89 
90 /**
91  * Key selection between fixed and random key during the batch capture.
92  */
93 bool sample_fixed = true;
94 
95 /**
96  * An array to store pre-computed round keys derived from the generation key.
97  * The generation key (key_gen) is specified in [DTR] Section 5.1.
98  * This key is used for generating all pseudo-random data for batch captures.
99  * kKeyGen[kAesKeyLength] = {0x12, 0x34, 0x56, 0x78,
100  * 0x9a, 0xbc, 0xde, 0xf1,
101  * 0x23, 0x45, 0x67, 0x89,
102  * 0xab, 0xcd, 0xe0, 0xf0};
103  */
104 static const uint32_t kKeyGenRoundKeys[(kAesKeyLength / 4) * 11] = {
105  0xab239a12, 0xcd45bc34, 0xe067de56, 0xf089f178, 0xbc1734ae, 0xe12c69d5,
106  0x836304da, 0x9262eb1a, 0xcb776054, 0x9d7c5039, 0x71f29195, 0x64f6947f,
107  0xd2196e0e, 0x2bb6ca9a, 0xc4b547d6, 0x6602f460, 0x528099f7, 0xd1fa4c86,
108  0xd317a2e5, 0x452321d5, 0x92c040d9, 0x8756ace0, 0xed3e298b, 0x92d7f4d5,
109  0xfc6eaeee, 0xc84f19b5, 0x3ed3edc4, 0x2bb96e9a, 0x7a86e846, 0x99511e07,
110  0x350bd835, 0xd6fd442a, 0x3c46c028, 0x47de8f91, 0x25101bc3, 0x9f49b4f0,
111  0x29155393, 0xb8ff21ae, 0x36130318, 0x79e6af1b, 0xa68f9ac9, 0xcd758aab,
112  0x88beadae, 0x8ef711be};
113 
114 /**
115  * Plaintext of the fixed set of fixed-vs-random-key TVLA
116  */
117 static uint8_t plaintext_fixed[kAesTextLength] = {
118  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
119  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
120 /**
121  * Key of the of the fixed set of fixed-vs-random-key TVLA
122  */
123 static uint8_t key_fixed[kAesTextLength] = {0x81, 0x1E, 0x37, 0x31, 0xB0, 0x12,
124  0x0A, 0x78, 0x42, 0x78, 0x1E, 0x22,
125  0xB2, 0x5C, 0xDD, 0xF9};
126 /**
127  * Plaintext of the random set of fixed-vs-random-key TVLA
128  */
129 static uint8_t plaintext_random[kAesTextLength] = {
130  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
131  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc};
132 /**
133  * Key of the random set of fixed-vs-random-key TVLA
134  */
135 static uint8_t key_random[kAesTextLength] = {0x53, 0x53, 0x53, 0x53, 0x53, 0x53,
136  0x53, 0x53, 0x53, 0x53, 0x53, 0x53,
137  0x53, 0x53, 0x53, 0x53};
138 /**
139  * Temp ciphertext variable
140  */
141 static uint8_t ciphertext_temp[kAesTextLength];
142 
143 /**
144  * batch_plaintext for batch capture to initially set it using command.
145  */
146 static uint8_t batch_plaintext[kAesTextLength];
147 
148 /**
149  * Block counter variable for manually handling reseeding operations of the
150  * masking PRNG inside the AES peripheral.
151  */
152 static uint32_t block_ctr;
153 
154 static dif_aes_t aes;
155 
156 dif_aes_transaction_t transaction = {
157  .operation = kDifAesOperationEncrypt,
158  .mode = kDifAesModeEcb,
159  .key_len = kDifAesKey128,
160  .manual_operation = kDifAesManualOperationManual,
161  .key_provider = kDifAesKeySoftwareProvided,
162  .mask_reseeding = kDifAesReseedPer8kBlock,
163  .reseed_on_key_change = false,
164  .force_masks = false,
165  .ctrl_aux_lock = false,
166 };
167 
168 /**
169  * Poll the IDLE AES register.
170  *
171  */
172 static void aes_sca_wait_for_idle(void) {
173  bool idle = false;
174  do {
176  } while (!idle);
177 }
178 
179 /**
180  * Load fixed seed into AES.
181  *
182  * Before calling this function, use
183  * aes_testutils_masking_prng_zero_output_seed() to initialize the entropy
184  * complex for performing AES SCA measurements with masking switched off. This
185  * function then loads the fixed seed into the AES, allowing the disable the
186  * masking.
187  *
188  * @param key Key.
189  * @param key_len Key length.
190  */
191 static void aes_sca_load_fixed_seed(void) {
192  aes_sca_wait_for_idle();
193  // Load magic seed such that masking is turned off. We need to do this after
194  // dif_aes_start() as then the force_masks is correctly set.
196  aes_sca_wait_for_idle();
197 }
198 
199 /**
200  * Mask and configure key.
201  *
202  * This function masks the provided key using a software LFSR and then
203  * configures the key into the AES peripheral. The masking can be disabled by
204  * initializing the LFSR to 0 (see `aes_serial_seed_lfsr()`). The key must be
205  * `kAesKeyLength` bytes long.
206  *
207  * @param key Key.
208  * @param key_len Key length.
209  */
210 static void aes_key_mask_and_config(const uint8_t *key, size_t key_len) {
211  SS_CHECK(key_len == kAesKeyLength);
212  dif_aes_key_share_t key_shares;
213  // Mask the provided key.
214  for (int i = 0; i < key_len / 4; ++i) {
215  key_shares.share1[i] = pentest_non_linear_layer(
216  pentest_linear_layer(pentest_next_lfsr(1, kPentestLfsrMasking)));
217  key_shares.share0[i] = *((uint32_t *)key + i) ^ key_shares.share1[i];
218  }
219  // Provide random shares for unused key bits.
220  for (size_t i = key_len / 4; i < kAesKeyLengthMax / 4; ++i) {
221  key_shares.share1[i] =
222  pentest_non_linear_layer(pentest_next_lfsr(1, kPentestLfsrMasking));
223  key_shares.share0[i] =
224  pentest_non_linear_layer(pentest_next_lfsr(1, kPentestLfsrMasking));
225  }
226 #ifndef OPENTITAN_IS_ENGLISHBREAKFAST
227  const dif_csrng_t csrng = {
229  const dif_edn_t edn0 = {
231 
232  CHECK_STATUS_OK(aes_testutils_masking_prng_zero_output_seed(&csrng, &edn0));
233 #endif
234  SS_CHECK_DIF_OK(dif_aes_start(&aes, &transaction, &key_shares, NULL));
235 
236 #ifndef OPENTITAN_IS_ENGLISHBREAKFAST
237  if (transaction.force_masks) {
238  // Disable masking. Force the masking PRNG output value to 0.
239  aes_sca_load_fixed_seed();
240  }
241 #endif
242 }
243 
244 /**
245  * Callback wrapper for AES manual trigger function.
246  */
247 static void aes_manual_trigger(void) {
249 }
250 
251 /**
252  * Simple serial 'k' (key set) command handler.
253  *
254  * This command is designed to set the fixed_key variable and in addition also
255  * configures the key into the AES peripheral.
256  *
257  * The key must be `kAesKeyLength` bytes long.
258  *
259  * @param key Key.
260  * @param key_len Key length.
261  */
262 static void aes_serial_key_set(const uint8_t *key, size_t key_len) {
263  SS_CHECK(key_len == kAesKeyLength);
264  memcpy(key_fixed, key, key_len);
265  aes_key_mask_and_config(key_fixed, key_len);
266  block_ctr = 0;
267 }
268 
269 /**
270  * Encrypts a plaintext using the AES peripheral.
271  *
272  * This function uses `pentest_call_and_sleep()` from the sca library to put
273  * Ibex to sleep in order to minimize noise during captures. The plaintext must
274  * be `kAesTextLength` bytes long.
275  *
276  * @param plaintext Plaintext.
277  * @param plaintext_len Length of the plaintext.
278  */
279 static void aes_encrypt(const uint8_t *plaintext, size_t plaintext_len) {
280  bool ready = false;
281  do {
283  } while (!ready);
284 
285  dif_aes_data_t data;
286  SS_CHECK(plaintext_len == sizeof(data.data));
287  memcpy(data.data, plaintext, plaintext_len);
288  SS_CHECK_DIF_OK(dif_aes_load_data(&aes, data));
289 
290  // Start AES operation (this triggers the capture) and go to sleep.
291  // Using the SecAesStartTriggerDelay hardware parameter, the AES unit is
292  // configured to start operation 40 cycles after receiving the start trigger.
293  // This allows Ibex to go to sleep in order to not disturb the capture.
294  pentest_set_trigger_high();
295  pentest_call_and_sleep(aes_manual_trigger, kIbexAesSleepCycles, false, false);
296  pentest_set_trigger_low();
297 }
298 
299 /**
300  * Wait until AES output is valid and then get ciphertext and send it over
301  * serial communication.
302  *
303  * @param only_first_word Send only the first word of the ciphertext.
304  */
305 static void aes_send_ciphertext(bool only_first_word) {
306  bool ready = false;
307  do {
309  } while (!ready);
310 
311  dif_aes_data_t ciphertext;
312  SS_CHECK_DIF_OK(dif_aes_read_output(&aes, &ciphertext));
313 
314  if (only_first_word) {
315  simple_serial_send_packet('r', (uint8_t *)ciphertext.data, 4);
316  } else {
317  simple_serial_send_packet('r', (uint8_t *)ciphertext.data, kAesTextLength);
318  }
319 }
320 
321 /**
322  * Simple serial 'p' (encrypt) command handler.
323  *
324  * Encrypts a `kAesTextLength` bytes long plaintext using the AES peripheral and
325  * sends the ciphertext over UART. This function also handles the trigger
326  * signal.
327  *
328  * @param plaintext Plaintext.
329  * @param plaintext_len Length of the plaintext.
330  */
331 static void aes_serial_single_encrypt(const uint8_t *plaintext,
332  size_t plaintext_len) {
333  SS_CHECK(plaintext_len == kAesTextLength);
334 
335  block_ctr++;
336  // Rewrite the key to reset the internal block counter. Otherwise, the AES
337  // peripheral might trigger the reseeding of the internal masking PRNG which
338  // disturbs SCA measurements.
339  if (block_ctr > kBlockCtrMax) {
340  aes_key_mask_and_config(key_fixed, kAesKeyLength);
341  block_ctr = 1;
342  }
343 
344  aes_encrypt(plaintext, plaintext_len);
345 
346  aes_send_ciphertext(false);
347 }
348 
349 /**
350  * Advances data for fvsr-key TVLA - fixed set.
351  *
352  * This function updates plaintext_fixed for fvsr-key TVLA, according
353  * to DTR recommendations.
354  */
355 static void aes_serial_advance_fixed(void) {
356  aes_sw_encrypt_block(plaintext_fixed, kKeyGenRoundKeys, ciphertext_temp);
357  memcpy(plaintext_fixed, ciphertext_temp, kAesTextLength);
358 }
359 
360 /**
361  * Advances data for fvsr-key TVLA - random set.
362  *
363  * This function updates plaintext_random and key_random for fvsr-key and
364  * random TVLA, according to DTR recommendations.
365  */
366 static void aes_serial_advance_random(void) {
367  aes_sw_encrypt_block(plaintext_random, kKeyGenRoundKeys, ciphertext_temp);
368  memcpy(plaintext_random, ciphertext_temp, kAesTextLength);
369  aes_sw_encrypt_block(key_random, kKeyGenRoundKeys, ciphertext_temp);
370  memcpy(key_random, ciphertext_temp, kAesTextLength);
371 }
372 
373 /**
374  * Advances data for fvsr-data TVLA - random set.
375  *
376  * This function updates plaintext_random for fvsr-data and
377  * TVLA, according to DTR recommendations, Section 5.1.
378  */
379 static void aes_serial_advance_random_data(void) {
380  aes_sw_encrypt_block(plaintext_random, kKeyGenRoundKeys, ciphertext_temp);
381  memcpy(plaintext_random, ciphertext_temp, kAesTextLength);
382 }
383 
384 /**
385  * Simple serial 'b' (batch encrypt) command handler.
386  *
387  * This command is designed to maximize the capture rate for side-channel
388  * attacks. Instead of expecting a plaintext and sending the resulting
389  * ciphertext from and to the host for each encryption, this command repeatedly
390  * encrypts random plaintexts that are generated on the device. This minimizes
391  * the overhead of UART communication and significantly improves the capture
392  * rate. The host must use the same PRNG to be able to compute the plaintext and
393  * the ciphertext of each trace.
394  *
395  * Packet payload must be a `uint32_t` representation of the number of
396  * encryptions to perform. Since generated plaintexts are not cached, there is
397  * no limit on the number of encryptions.
398  *
399  * The PRNG should be initialized using the 's' (seed PRNG) command before
400  * starting batch encryption. In addition, the key should also be set
401  * using 'k' (key set) command before starting batch captures.
402  *
403  * Note that the host can partially verify this operation by checking the
404  * contents of the 'r' (ciphertext) packet that is sent at the end.
405  *
406  * @param data Packet payload.
407  * @param data_len Packet payload length.
408  */
409 static void aes_serial_batch_encrypt(const uint8_t *data, size_t data_len) {
410  uint32_t num_encryptions = 0;
411  SS_CHECK(data_len == sizeof(num_encryptions));
412  num_encryptions = read_32(data);
413 
414  block_ctr += num_encryptions;
415  // Rewrite the key to reset the internal block counter. Otherwise, the AES
416  // peripheral might trigger the reseeding of the internal masking PRNG which
417  // disturbs SCA measurements.
418  if (block_ctr > kBlockCtrMax) {
419  aes_key_mask_and_config(key_fixed, kAesKeyLength);
420  block_ctr = num_encryptions;
421  }
422 
423  for (uint32_t i = 0; i < num_encryptions; ++i) {
424  aes_encrypt(plaintext_random, kAesTextLength);
425  aes_serial_advance_random();
426  }
427 
428  aes_send_ciphertext(true);
429 }
430 
431 /**
432  * Simple serial 'a' (alternative batch encrypt) command handler.
433  *
434  * This command is designed to maximize the capture rate for side-channel
435  * attacks. It uses the first supplied plaintext and repeats AES encryptions
436  * by using every ciphertext as next plaintext with a constant key. This
437  * minimizes the overhead of UART communication and significantly improves the
438  * capture rate.
439 
440  * Packet payload must be a `uint32_t` representation of the number of
441  * encryptions to perform. Since generated plaintexts are not cached, there is
442  * no limit on the number of encryptions.
443  *
444  * The key should also be set using 'k' (key set) command.
445  *
446  * The host can verify the operation by checking the last 'r' (ciphertext)
447  * packet that is sent at the end.
448  *
449  * @param data Packet payload.
450  * @param data_len Packet payload length.
451  */
452 static void aes_serial_batch_alternative_encrypt(const uint8_t *data,
453  size_t data_len) {
454  // Get num_encryptions from input
455  uint32_t num_encryptions = 0;
456  SS_CHECK(data_len == sizeof(num_encryptions));
457  num_encryptions = read_32(data);
458 
459  // Add to current block_ctr to check if > kBlockCtrMax
460  block_ctr += num_encryptions;
461  // Rewrite the key to reset the internal block counter. Otherwise, the AES
462  // peripheral might trigger the reseeding of the internal masking PRNG which
463  // disturbs SCA measurements.
464  if (block_ctr > kBlockCtrMax) {
465  aes_key_mask_and_config(key_fixed, kAesKeyLength);
466  block_ctr = num_encryptions;
467  }
468 
469  // First plaintext has been set through command into batch_plaintext
470 
471  // Set trigger high outside of loop
472  // On FPGA, the trigger is AND-ed with AES !IDLE and creates a LO-HI-LO per
473  // AES operation
474  dif_aes_data_t ciphertext;
475  for (uint32_t i = 0; i < num_encryptions; ++i) {
476  // Encrypt
477  aes_encrypt(batch_plaintext, kAesTextLength);
478 
479  // Get ciphertext
480  bool ready = false;
481  do {
484  } while (!ready);
485  SS_CHECK_DIF_OK(dif_aes_read_output(&aes, &ciphertext));
486 
487  // Use ciphertext as next plaintext (incl. next call to this function)
488  memcpy(batch_plaintext, ciphertext.data, kAesTextLength);
489  }
490  // Acknowledge command
492  // send last ciphertext
493  simple_serial_send_packet('r', (uint8_t *)ciphertext.data, kAesTextLength);
494 }
495 
496 /**
497  * Simple serial 'i' (batch plaintext) command handler.
498  *
499  * This command is designed to set the initial plaintext for
500  * aes_serial_batch_alternative_encrypt.
501  *
502  * The plaintext must be `kAesTextLength` bytes long.
503  *
504  * @param plaintext.
505  * @param len.
506  */
507 static void aes_serial_batch_plaintext_set(const uint8_t *plaintext,
508  size_t len) {
509  SS_CHECK(len == kAesTextLength);
510  memcpy(batch_plaintext, plaintext, len);
511 }
512 
513 /**
514  * Simple serial 'f' (fvsr key set) command handler.
515  *
516  * This command is designed to set the fixed key which is used for fvsr key TVLA
517  * captures.
518  *
519  * The key must be `kAesKeyLength` bytes long.
520  *
521  * @param key Key.
522  * @param key_len Key length.
523  */
524 static void aes_serial_fvsr_key_set(const uint8_t *key, size_t key_len) {
525  SS_CHECK(key_len == kAesKeyLength);
526  memcpy(key_fixed, key, key_len);
527 }
528 
529 /**
530  * Simple serial 'g' (fixed vs random key batch generate) command handler.
531  *
532  * This command generates random plaintexts and fixed or random keys using PRNG
533  * for AES fixed vs random key batch capture in order to remove fake leakage.
534  * Fixed or random key sequence is also determined here by using the lsb bit of
535  * the plaintext. In order to simplify the analysis, the first encryption has to
536  * use fixed key. The data collection method is based on the derived test
537  * requirements (DTR) for TVLA:
538  * https://www.rambus.com/wp-content/uploads/2015/08/TVLA-DTR-with-AES.pdf
539  * The measurements are taken by using either fixed or randomly selected keys.
540  * In addition, a PRNG is used for random key and plaintext generation instead
541  * of AES algorithm as specified in the TVLA DTR.
542  *
543  * Packet payload must be a `uint32_t` representation of the number of
544  * encryptions to perform. Number of operations of a batch should not be greater
545  * than the 'kNumBatchOpsMax' value.
546  *
547  * The PRNG should be initialized using the 's' (seed PRNG) command before
548  * starting batch captures. In addition, the fixed key should also be set
549  * using 't' (fvsr key set) command before starting batch captures.
550  *
551  * @param data Packet payload.
552  * @param data_len Packet payload length.
553  */
554 static void aes_serial_fvsr_key_batch_generate(const uint8_t *data,
555  size_t data_len) {
556  uint32_t num_encryptions = 0;
557  SS_CHECK(data_len == sizeof(num_encryptions));
558  num_encryptions = read_32(data);
559  SS_CHECK(num_encryptions <= kNumBatchOpsMax);
560 
561  for (uint32_t i = 0; i < num_encryptions; ++i) {
562  if (sample_fixed) {
563  memcpy(batch_keys[i], key_fixed, kAesKeyLength);
564  memcpy(batch_plaintexts[i], plaintext_fixed, kAesKeyLength);
565  aes_serial_advance_fixed();
566  } else {
567  memcpy(batch_keys[i], key_random, kAesKeyLength);
568  memcpy(batch_plaintexts[i], plaintext_random, kAesKeyLength);
569  aes_serial_advance_random();
570  }
571  sample_fixed = batch_plaintexts[i][0] & 0x1;
572  }
573 }
574 
575 /**
576  * Simple serial 'e' (fixed vs random key batch encrypt and generate) command
577  * handler.
578  *
579  * This command is designed to maximize the capture rate for side-channel
580  * attacks. Instead of expecting a plaintext and sending the resulting
581  * ciphertext from and to the host for each encryption, this command repeatedly
582  * encrypts random plaintexts that are generated on the device. The data
583  * collection method is based on the derived test requirements (DTR) for TVLA:
584  * https://www.rambus.com/wp-content/uploads/2015/08/TVLA-DTR-with-AES.pdf
585  * The measurements are taken by using either fixed or randomly selected keys.
586  * In order to simplify the analysis, the first encryption has to use fixed key.
587  * This minimizes the overhead of UART communication and significantly improves
588  * the capture rate.
589  *
590  * Packet payload must be a `uint32_t` representation of the number of
591  * encryptions to perform. Number of operations of a batch should not be greater
592  * than the 'kNumBatchOpsMax' value.
593  *
594  * Note that the host can partially verify this operation by checking the
595  * contents of the 'r' (last ciphertext) packet that is sent at the end of every
596  * batch.
597  *
598  * @param data Packet payload.
599  * @param data_len Packet payload length.
600  */
601 static void aes_serial_fvsr_key_batch_encrypt(const uint8_t *data,
602  size_t data_len) {
603  uint32_t num_encryptions = 0;
604  SS_CHECK(data_len == sizeof(num_encryptions));
605  num_encryptions = read_32(data);
606  SS_CHECK(num_encryptions <= kNumBatchOpsMax);
607 
608  for (uint32_t i = 0; i < num_encryptions; ++i) {
609  aes_key_mask_and_config(batch_keys[i], kAesKeyLength);
610  aes_encrypt(batch_plaintexts[i], kAesTextLength);
611  }
612 
613  // Acknowledge command
615 
616  aes_send_ciphertext(false);
617 
618  // Start to generate random keys and plaintexts for the next batch when the
619  // waves are getting from scope by the host to increase capture rate.
620  aes_serial_fvsr_key_batch_generate(data, data_len);
621 }
622 
623 /**
624  * Simple serial 'h' (fixed vs random data batch encrypt) command handler.
625  *
626  * This command is designed to maximize the capture rate for side-channel
627  * attacks. Instead of expecting a plaintext and sending the resulting
628  * ciphertext from and to the host for each encryption, this command repeatedly
629  * encrypts plaintexts that are generated on the device. The data
630  * collection method is based on the derived test requirements (DTR) for TVLA:
631  * https://www.rambus.com/wp-content/uploads/2015/08/TVLA-DTR-with-AES.pdf
632  * The measurements are taken by using either fixed or randomly selected
633  * plaintexts. In order to simplify the analysis, the first encryption has to
634  * use fixed plaintext. This minimizes the overhead of UART communication and
635  * significantly improves the capture rate. The host must use the same PRNG to
636  * be able to compute the random plaintext and the ciphertext of each trace.
637  *
638  * Packet payload must be a `uint32_t` representation of the number of
639  * encryptions to perform. Number of operations of a batch should not be greater
640  * than the 'kNumBatchOpsMax' value.
641  *
642  * Note that the host can partially verify this operation by checking the
643  * contents of the 'r' (last ciphertext) packet that is sent at the end of every
644  * batch.
645  *
646  * @param data Packet payload.
647  * @param data_len Packet payload length.
648  */
649 static void aes_serial_fvsr_data_batch_encrypt(const uint8_t *data,
650  size_t data_len) {
651  uint32_t num_encryptions = 0;
652  SS_CHECK(data_len == sizeof(num_encryptions));
653  num_encryptions = read_32(data);
654  SS_CHECK(num_encryptions <= kNumBatchOpsMax);
655 
656  for (uint32_t i = 0; i < num_encryptions; ++i) {
657  // The same key is used for both fixed and random data set.
658  memcpy(batch_keys[i], key_fixed, kAesKeyLength);
659  if (sample_fixed) {
660  memcpy(batch_plaintexts[i], plaintext_fixed, kAesKeyLength);
661  } else {
662  memcpy(batch_plaintexts[i], plaintext_random, kAesKeyLength);
663  aes_serial_advance_random_data();
664  }
665  sample_fixed = pentest_next_lfsr(1, kPentestLfsrOrder) & 0x1;
666  }
667 
668  for (uint32_t i = 0; i < num_encryptions; ++i) {
669  aes_key_mask_and_config(batch_keys[i], kAesKeyLength);
670  aes_encrypt(batch_plaintexts[i], kAesTextLength);
671  }
672 
673  // Acknowledge command
675 
676  aes_send_ciphertext(false);
677 }
678 
679 /**
680  * Simple serial 'l' (seed lfsr) command handler.
681  *
682  * This function only supports 4-byte seeds.
683  * Enables/disables masking depending on seed value, i.e. 0 for disable.
684  *
685  * @param seed A buffer holding the seed.
686  */
687 static void aes_serial_seed_lfsr(const uint8_t *seed, size_t seed_len) {
688  SS_CHECK(seed_len == sizeof(uint32_t));
689  uint32_t seed_local = read_32(seed);
690  if (seed_local == 0) {
691  // disable masking
692  transaction.force_masks = true;
693  } else {
694  // enable masking
695  transaction.force_masks = false;
696  }
697  pentest_seed_lfsr(seed_local, kPentestLfsrMasking);
698 }
699 
700 /**
701  * Simple serial 'j' (seed lfsr) command handler.
702  *
703  * This function only supports 4-byte seeds.
704  * Sets the seed for the LFSR used to determine the order of measurements
705  * in fixed-vs-random-data dataset.
706  *
707  * @param seed A buffer holding the seed.
708  */
709 static void aes_serial_seed_lfsr_order(const uint8_t *seed, size_t seed_len) {
710  SS_CHECK(seed_len == sizeof(uint32_t));
711  uint32_t seed_local = read_32(seed);
712  pentest_seed_lfsr(seed_local, kPentestLfsrOrder);
713 }
714 
715 /**
716  * Simple serial 'd' (set starting values) command handler.
717  *
718  * This function sets starting values for FvsR data generation
719  * if the received value is 1.
720  * These values are specified in DTR for AES TVLA
721  *
722  * @param data Input command. For now only data == 1 resets values.
723  */
724 static void aes_serial_set_default_values(const uint8_t *data,
725  size_t data_len) {
726  SS_CHECK(data_len == sizeof(uint32_t));
727  uint32_t command = 0;
728  command = read_32(data);
729  // Starting constants for fixed-vs-random key, DTR Section 5.3
730  static const uint8_t kPlaintextFixedStartFvsrKey[kAesTextLength] = {
731  0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
732  0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
733  static const uint8_t kKeyFixedStartFvsrKey[kAesTextLength] = {
734  0x81, 0x1E, 0x37, 0x31, 0xB0, 0x12, 0x0A, 0x78,
735  0x42, 0x78, 0x1E, 0x22, 0xB2, 0x5C, 0xDD, 0xF9};
736  static const uint8_t kPlaintextRandomStartFvsrKey[kAesTextLength] = {
737  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
738  0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc};
739  static const uint8_t kKeyRandomStartFvsrKey[kAesTextLength] = {
740  0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53,
741  0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53};
742  // Starting constants for fixed-vs-random data, DTR Section 5.1
743  static const uint8_t kPlaintextFixedStartFvsrData[kAesTextLength] = {
744  0xDA, 0x39, 0xA3, 0xEE, 0x5E, 0x6B, 0x4B, 0x0D,
745  0x32, 0x55, 0xBF, 0xEF, 0x95, 0x60, 0x18, 0x90};
746  static const uint8_t kPlaintextRandomStartFvsrData[kAesTextLength] = {
747  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
748  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
749  static const uint8_t kKeyStartFvsrData[kAesTextLength] = {
750  0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
751  0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0};
752 
753  // Initial state of the prng
754  static const uint32_t kPrngInitialState = 0x99999999;
755 
756  // If fixed-vs-random key analysis
757  if (command == 1) {
758  memcpy(plaintext_fixed, kPlaintextFixedStartFvsrKey, kAesTextLength);
759  memcpy(key_fixed, kKeyFixedStartFvsrKey, kAesKeyLength);
760  memcpy(plaintext_random, kPlaintextRandomStartFvsrKey, kAesTextLength);
761  memcpy(key_random, kKeyRandomStartFvsrKey, kAesKeyLength);
762  }
763 
764  // If fixed-vs-random data analysis
765  if (command == 2) {
766  memcpy(plaintext_fixed, kPlaintextFixedStartFvsrData, kAesTextLength);
767  memcpy(key_fixed, kKeyStartFvsrData, kAesKeyLength);
768  memcpy(plaintext_random, kPlaintextRandomStartFvsrData, kAesTextLength);
769  }
770 
771  pentest_seed_lfsr(kPrngInitialState, kPentestLfsrOrder);
772 }
773 
774 /**
775  * Initializes the AES peripheral.
776  */
777 static void init_aes(void) {
781 }
782 
783 /**
784  * Main function.
785  *
786  * Initializes peripherals and processes simple serial packets received over
787  * UART.
788  */
789 bool test_main(void) {
790  pentest_init(kPentestTriggerSourceAes,
791  kPentestPeripheralIoDiv4 | kPentestPeripheralAes);
792 
793  LOG_INFO("Running AES serial");
794 
795  LOG_INFO("Initializing simple serial interface to capture board.");
796  simple_serial_init(pentest_get_uart());
797  simple_serial_register_handler('k', aes_serial_key_set);
798  simple_serial_register_handler('p', aes_serial_single_encrypt);
799  simple_serial_register_handler('b', aes_serial_batch_encrypt);
800  simple_serial_register_handler('f', aes_serial_fvsr_key_set);
801  simple_serial_register_handler('g', aes_serial_fvsr_key_batch_generate);
802  simple_serial_register_handler('e', aes_serial_fvsr_key_batch_encrypt);
803  simple_serial_register_handler('h', aes_serial_fvsr_data_batch_encrypt);
804  simple_serial_register_handler('l', aes_serial_seed_lfsr);
805  simple_serial_register_handler('j', aes_serial_seed_lfsr_order);
806  simple_serial_register_handler('a', aes_serial_batch_alternative_encrypt);
807  simple_serial_register_handler('i', aes_serial_batch_plaintext_set);
808  simple_serial_register_handler('d', aes_serial_set_default_values);
809 
810  LOG_INFO("Initializing AES unit.");
811  init_aes();
812 
813 #ifndef OPENTITAN_IS_ENGLISHBREAKFAST
814  if (transaction.force_masks) {
815  LOG_INFO("Initializing entropy complex.");
816  const dif_csrng_t csrng = {
818  const dif_edn_t edn0 = {
820 
821  CHECK_STATUS_OK(aes_testutils_masking_prng_zero_output_seed(&csrng, &edn0));
822  aes_sca_load_fixed_seed();
823  }
824 #endif
825  CHECK_DIF_OK(dif_aes_trigger(&aes, kDifAesTriggerDataOutClear));
826 
827  LOG_INFO("Starting simple serial packet handling.");
828  while (true) {
830  }
831 }