@@ -42,6 +42,20 @@ enum {
4242 kAesGcmContextNumWords = sizeof (aes_gcm_context_t ) / sizeof (uint32_t ),
4343};
4444
45+ /**
46+ * AES cleanup guard.
47+ */
48+ static void aes_wipe_guard (uint32_t * dummy ) { (void )aes_clear (); }
49+
50+ /**
51+ * Sideload cleanup guard.
52+ */
53+ static void sideload_wipe_guard (hardened_bool_t * is_sideloaded ) {
54+ if (* is_sideloaded == kHardenedBoolTrue ) {
55+ (void )keymgr_sideload_clear_aes ();
56+ }
57+ }
58+
4559/**
4660 * Save an AES-GCM context.
4761 *
@@ -252,30 +266,6 @@ static status_t load_key_if_sideloaded(const aes_key_t key) {
252266 return keymgr_generate_key_aes (diversification );
253267}
254268
255- /**
256- * Clear the sideload slot if the AES key was sideloaded.
257- *
258- * It is important to clear the sideload slot before returning to the caller so
259- * that other applications can't access the key in between operations.
260- *
261- * If the key is not a sideloaded key, this function does nothing.
262- *
263- * @param key Key that was possibly loaded.
264- * @return OK or errror.
265- */
266- static status_t clear_key_if_sideloaded (const aes_key_t key ) {
267- if (launder32 (key .sideload ) == kHardenedBoolFalse ) {
268- HARDENED_CHECK_EQ (key .sideload , launder32 (kHardenedBoolFalse ));
269- return OTCRYPTO_OK ;
270- } else if (launder32 (key .sideload ) != kHardenedBoolTrue ) {
271- // COVERAGE (SW ERR) This is an internal function, the aes key's sideload is
272- // set internal by good parameters.
273- return OTCRYPTO_BAD_ARGS ;
274- }
275- HARDENED_CHECK_EQ (key .sideload , launder32 (kHardenedBoolTrue ));
276- return keymgr_sideload_clear_aes ();
277- }
278-
279269otcrypto_status_t otcrypto_aes_gcm_encrypt (
280270 otcrypto_blinded_key_t * key , const otcrypto_const_byte_buf_t * plaintext ,
281271 const otcrypto_const_word32_buf_t * iv , const otcrypto_const_byte_buf_t * aad ,
@@ -300,6 +290,10 @@ otcrypto_status_t otcrypto_aes_gcm_encrypt(
300290 }
301291#endif
302292
293+ hardened_bool_t is_sideloaded __attribute__((cleanup (sideload_wipe_guard ))) =
294+ kHardenedBoolFalse ;
295+ uint32_t hw_cleanup_guard __attribute__((cleanup (aes_wipe_guard ))) = 1 ;
296+
303297 // Ensure the plaintext and ciphertext lengths match.
304298 if (launder32 (ciphertext -> len ) != plaintext -> len ) {
305299 return OTCRYPTO_BAD_ARGS ;
@@ -315,6 +309,9 @@ otcrypto_status_t otcrypto_aes_gcm_encrypt(
315309 // Construct the AES key.
316310 aes_key_t aes_key ;
317311 HARDENED_TRY (aes_gcm_key_construct (key , & aes_key ));
312+ if (launder32 (aes_key .sideload ) == kHardenedBoolTrue ) {
313+ is_sideloaded = kHardenedBoolTrue ;
314+ }
318315 HARDENED_TRY (load_key_if_sideloaded (aes_key ));
319316
320317 // Call the core encryption operation.
@@ -323,8 +320,6 @@ otcrypto_status_t otcrypto_aes_gcm_encrypt(
323320 auth_tag -> len , key -> config .security_level ,
324321 auth_tag -> data , ciphertext -> data ));
325322
326- HARDENED_TRY (clear_key_if_sideloaded (aes_key ));
327-
328323 // Verify the input buffers
329324 HARDENED_CHECK_EQ (kHardenedBoolTrue , OTCRYPTO_CHECK_BUF (plaintext ));
330325 HARDENED_CHECK_EQ (kHardenedBoolTrue , OTCRYPTO_CHECK_BUF (iv ));
@@ -359,9 +354,16 @@ otcrypto_status_t otcrypto_aes_gcm_decrypt(
359354 }
360355#endif
361356
357+ hardened_bool_t is_sideloaded __attribute__((cleanup (sideload_wipe_guard ))) =
358+ kHardenedBoolFalse ;
359+ uint32_t hw_cleanup_guard __attribute__((cleanup (aes_wipe_guard ))) = 1 ;
360+
362361 // Construct the AES key.
363362 aes_key_t aes_key ;
364363 HARDENED_TRY (aes_gcm_key_construct (key , & aes_key ));
364+ if (launder32 (aes_key .sideload ) == kHardenedBoolTrue ) {
365+ is_sideloaded = kHardenedBoolTrue ;
366+ }
365367 HARDENED_TRY (load_key_if_sideloaded (aes_key ));
366368
367369 // Ensure the plaintext and ciphertext lengths match.
@@ -379,8 +381,6 @@ otcrypto_status_t otcrypto_aes_gcm_decrypt(
379381 auth_tag -> len , auth_tag -> data , plaintext -> data ,
380382 key -> config .security_level , success ));
381383
382- HARDENED_TRY (clear_key_if_sideloaded (aes_key ));
383-
384384 // Verify the input buffers
385385 HARDENED_CHECK_EQ (kHardenedBoolTrue , OTCRYPTO_CHECK_BUF (plaintext ));
386386 HARDENED_CHECK_EQ (kHardenedBoolTrue , OTCRYPTO_CHECK_BUF (iv ));
@@ -401,19 +401,25 @@ otcrypto_status_t otcrypto_aes_gcm_encrypt_init(
401401 }
402402#endif
403403
404+ hardened_bool_t is_sideloaded __attribute__((cleanup (sideload_wipe_guard ))) =
405+ kHardenedBoolFalse ;
406+ uint32_t hw_cleanup_guard __attribute__((cleanup (aes_wipe_guard ))) = 1 ;
407+
404408 // Construct the AES key.
405409 aes_key_t aes_key ;
406410 HARDENED_TRY (aes_gcm_key_construct (key , & aes_key ));
411+ if (launder32 (aes_key .sideload ) == kHardenedBoolTrue ) {
412+ is_sideloaded = kHardenedBoolTrue ;
413+ }
407414 HARDENED_TRY (load_key_if_sideloaded (aes_key ));
408415
409416 // Call the internal init operation.
410417 aes_gcm_context_t internal_ctx ;
411418 internal_ctx .security_level = key -> config .security_level ;
412419 HARDENED_TRY (aes_gcm_encrypt_init (aes_key , iv -> len , iv -> data , & internal_ctx ));
413420
414- // Save the context and clear the key if needed .
421+ // Save the context.
415422 HARDENED_TRY (gcm_context_save (& internal_ctx , ctx ));
416- HARDENED_TRY (clear_key_if_sideloaded (internal_ctx .key ));
417423
418424 // Verify the input buffer
419425 HARDENED_CHECK_EQ (kHardenedBoolTrue , OTCRYPTO_CHECK_BUF (iv ));
@@ -431,19 +437,25 @@ otcrypto_status_t otcrypto_aes_gcm_decrypt_init(
431437 }
432438#endif
433439
440+ hardened_bool_t is_sideloaded __attribute__((cleanup (sideload_wipe_guard ))) =
441+ kHardenedBoolFalse ;
442+ uint32_t hw_cleanup_guard __attribute__((cleanup (aes_wipe_guard ))) = 1 ;
443+
434444 // Construct the AES key.
435445 aes_key_t aes_key ;
436446 HARDENED_TRY (aes_gcm_key_construct (key , & aes_key ));
447+ if (launder32 (aes_key .sideload ) == kHardenedBoolTrue ) {
448+ is_sideloaded = kHardenedBoolTrue ;
449+ }
437450 HARDENED_TRY (load_key_if_sideloaded (aes_key ));
438451
439452 // Call the internal init operation.
440453 aes_gcm_context_t internal_ctx ;
441454 internal_ctx .security_level = key -> config .security_level ;
442455 HARDENED_TRY (aes_gcm_decrypt_init (aes_key , iv -> len , iv -> data , & internal_ctx ));
443456
444- // Save the context and clear the key if needed .
457+ // Save the context.
445458 HARDENED_TRY (gcm_context_save (& internal_ctx , ctx ));
446- HARDENED_TRY (clear_key_if_sideloaded (internal_ctx .key ));
447459
448460 // Verify the input buffer
449461 HARDENED_CHECK_EQ (kHardenedBoolTrue , OTCRYPTO_CHECK_BUF (iv ));
@@ -465,17 +477,23 @@ otcrypto_status_t otcrypto_aes_gcm_update_aad(
465477 return OTCRYPTO_OK ;
466478 }
467479
480+ hardened_bool_t is_sideloaded __attribute__((cleanup (sideload_wipe_guard ))) =
481+ kHardenedBoolFalse ;
482+ uint32_t hw_cleanup_guard __attribute__((cleanup (aes_wipe_guard ))) = 1 ;
483+
468484 // Restore the AES-GCM context object and load the key if needed.
469485 aes_gcm_context_t internal_ctx ;
470486 HARDENED_TRY (gcm_context_restore (ctx , & internal_ctx ));
487+ if (launder32 (internal_ctx .key .sideload ) == kHardenedBoolTrue ) {
488+ is_sideloaded = kHardenedBoolTrue ;
489+ }
471490 HARDENED_TRY (load_key_if_sideloaded (internal_ctx .key ));
472491
473492 // Call the internal update operation.
474493 HARDENED_TRY (aes_gcm_update_aad (& internal_ctx , aad -> len , aad -> data ));
475494
476- // Save the context and clear the key if needed .
495+ // Save the context.
477496 HARDENED_TRY (gcm_context_save (& internal_ctx , ctx ));
478- HARDENED_TRY (clear_key_if_sideloaded (internal_ctx .key ));
479497
480498 // Verify the input buffer
481499 HARDENED_CHECK_EQ (kHardenedBoolTrue , OTCRYPTO_CHECK_BUF (aad ));
@@ -500,9 +518,16 @@ otcrypto_status_t otcrypto_aes_gcm_update_encrypted_data(
500518 return OTCRYPTO_OK ;
501519 }
502520
521+ hardened_bool_t is_sideloaded __attribute__((cleanup (sideload_wipe_guard ))) =
522+ kHardenedBoolFalse ;
523+ uint32_t hw_cleanup_guard __attribute__((cleanup (aes_wipe_guard ))) = 1 ;
524+
503525 // Restore the AES-GCM context object and load the key if needed.
504526 aes_gcm_context_t internal_ctx ;
505527 HARDENED_TRY (gcm_context_restore (ctx , & internal_ctx ));
528+ if (launder32 (internal_ctx .key .sideload ) == kHardenedBoolTrue ) {
529+ is_sideloaded = kHardenedBoolTrue ;
530+ }
506531 HARDENED_TRY (load_key_if_sideloaded (internal_ctx .key ));
507532 // Remask the key if it is not sideloaded.
508533 HARDENED_TRY (gcm_remask_key (& internal_ctx ));
@@ -526,9 +551,8 @@ otcrypto_status_t otcrypto_aes_gcm_update_encrypted_data(
526551 input -> data , output_bytes_written ,
527552 output -> data ));
528553
529- // Save the context and clear the key if needed .
554+ // Save the context.
530555 HARDENED_TRY (gcm_context_save (& internal_ctx , ctx ));
531- HARDENED_TRY (clear_key_if_sideloaded (internal_ctx .key ));
532556
533557 // Verify the input buffers
534558 HARDENED_CHECK_EQ (kHardenedBoolTrue , OTCRYPTO_CHECK_BUF (input ));
@@ -559,9 +583,16 @@ otcrypto_status_t otcrypto_aes_gcm_encrypt_final(
559583 // Randomize the tag before the operation.
560584 HARDENED_TRY (hardened_memshred (auth_tag -> data , auth_tag -> len ));
561585
586+ hardened_bool_t is_sideloaded __attribute__((cleanup (sideload_wipe_guard ))) =
587+ kHardenedBoolFalse ;
588+ uint32_t hw_cleanup_guard __attribute__((cleanup (aes_wipe_guard ))) = 1 ;
589+
562590 // Restore the AES-GCM context object and load the key if needed.
563591 aes_gcm_context_t internal_ctx ;
564592 HARDENED_TRY (gcm_context_restore (ctx , & internal_ctx ));
593+ if (launder32 (internal_ctx .key .sideload ) == kHardenedBoolTrue ) {
594+ is_sideloaded = kHardenedBoolTrue ;
595+ }
565596 HARDENED_TRY (load_key_if_sideloaded (internal_ctx .key ));
566597 // Remask the key if it is not sideloaded.
567598 HARDENED_TRY (gcm_remask_key (& internal_ctx ));
@@ -578,9 +609,8 @@ otcrypto_status_t otcrypto_aes_gcm_encrypt_final(
578609 auth_tag -> data , ciphertext_bytes_written ,
579610 ciphertext -> data ));
580611
581- // Clear the context and the key if needed .
612+ // Clear the context.
582613 HARDENED_TRY (hardened_memshred (ctx -> data , ARRAYSIZE (ctx -> data )));
583- HARDENED_TRY (clear_key_if_sideloaded (internal_ctx .key ));
584614
585615 // Verify the input buffers
586616 HARDENED_CHECK_EQ (kHardenedBoolTrue , OTCRYPTO_CHECK_BUF (ciphertext ));
@@ -609,9 +639,16 @@ otcrypto_status_t otcrypto_aes_gcm_decrypt_final(
609639 // Check the tag length.
610640 HARDENED_TRY (aes_gcm_check_tag_length (auth_tag -> len , tag_len ));
611641
642+ hardened_bool_t is_sideloaded __attribute__((cleanup (sideload_wipe_guard ))) =
643+ kHardenedBoolFalse ;
644+ uint32_t hw_cleanup_guard __attribute__((cleanup (aes_wipe_guard ))) = 1 ;
645+
612646 // Restore the AES-GCM context object and load the key if needed.
613647 aes_gcm_context_t internal_ctx ;
614648 HARDENED_TRY (gcm_context_restore (ctx , & internal_ctx ));
649+ if (launder32 (internal_ctx .key .sideload ) == kHardenedBoolTrue ) {
650+ is_sideloaded = kHardenedBoolTrue ;
651+ }
615652 HARDENED_TRY (load_key_if_sideloaded (internal_ctx .key ));
616653 // Remask the key if it is not sideloaded.
617654 HARDENED_TRY (gcm_remask_key (& internal_ctx ));
@@ -628,9 +665,8 @@ otcrypto_status_t otcrypto_aes_gcm_decrypt_final(
628665 auth_tag -> data , plaintext_bytes_written ,
629666 plaintext -> data , success ));
630667
631- // Clear the context and the key if needed .
668+ // Clear the context.
632669 HARDENED_TRY (hardened_memshred (ctx -> data , ARRAYSIZE (ctx -> data )));
633- HARDENED_TRY (clear_key_if_sideloaded (internal_ctx .key ));
634670
635671 // Verify the input buffers
636672 HARDENED_CHECK_EQ (kHardenedBoolTrue , OTCRYPTO_CHECK_BUF (auth_tag ));
0 commit comments