Skip to content

Commit 8ffb16e

Browse files
committed
[crypto] Re-mask AES-GCM keys
As suggested in #27243, this commit regularly remasks the key that is used for AES-GCM. Signed-off-by: Pascal Nasahl <nasahlpa@lowrisc.org>
1 parent 8dadc05 commit 8ffb16e

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

sw/device/lib/crypto/impl/aes_gcm.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,34 @@ static inline void gcm_context_restore(otcrypto_aes_gcm_context_t *api_ctx,
6666
kAesGcmContextNumWords);
6767
}
6868

69+
/**
70+
* Remask the key if it is not sideloaded.
71+
*
72+
* Generate a fresh mask and apply it to the current key.
73+
*
74+
* @param[in,out] internal_ctx Internal context object.
75+
* @return Result of the operation.
76+
*/
77+
status_t gcm_remask_key(aes_gcm_context_t *internal_ctx) {
78+
if (launder32(internal_ctx->key.sideload) == kHardenedBoolFalse) {
79+
HARDENED_CHECK_EQ(internal_ctx->key.sideload, kHardenedBoolFalse);
80+
81+
// Generate a fresh mask the size of one share.
82+
uint32_t mask[internal_ctx->key.key_len];
83+
hardened_memshred(mask, internal_ctx->key.key_len);
84+
85+
// XOR each share with the mask.
86+
HARDENED_TRY(hardened_xor((uint32_t *)internal_ctx->key.key_shares[0], mask,
87+
internal_ctx->key.key_len));
88+
HARDENED_TRY(hardened_xor((uint32_t *)internal_ctx->key.key_shares[1], mask,
89+
internal_ctx->key.key_len));
90+
} else {
91+
HARDENED_CHECK_EQ(internal_ctx->key.sideload, kHardenedBoolTrue);
92+
}
93+
94+
return OTCRYPTO_OK;
95+
}
96+
6997
/**
7098
* Construct the underlying AES key for AES-GCM.
7199
*
@@ -427,6 +455,8 @@ otcrypto_status_t otcrypto_aes_gcm_update_encrypted_data(
427455
aes_gcm_context_t internal_ctx;
428456
gcm_context_restore(ctx, &internal_ctx);
429457
HARDENED_TRY(load_key_if_sideloaded(internal_ctx.key));
458+
// Remask the key if it is not sideloaded.
459+
HARDENED_TRY(gcm_remask_key(&internal_ctx));
430460

431461
// The output buffer must be long enough to hold all full blocks that will
432462
// exist after `input` is added.
@@ -474,6 +504,8 @@ otcrypto_status_t otcrypto_aes_gcm_encrypt_final(
474504
aes_gcm_context_t internal_ctx;
475505
gcm_context_restore(ctx, &internal_ctx);
476506
HARDENED_TRY(load_key_if_sideloaded(internal_ctx.key));
507+
// Remask the key if it is not sideloaded.
508+
HARDENED_TRY(gcm_remask_key(&internal_ctx));
477509

478510
// If the partial block is nonempty, the output must be at least as long as
479511
// the partial block.
@@ -517,6 +549,8 @@ otcrypto_status_t otcrypto_aes_gcm_decrypt_final(
517549
aes_gcm_context_t internal_ctx;
518550
gcm_context_restore(ctx, &internal_ctx);
519551
HARDENED_TRY(load_key_if_sideloaded(internal_ctx.key));
552+
// Remask the key if it is not sideloaded.
553+
HARDENED_TRY(gcm_remask_key(&internal_ctx));
520554

521555
// If the partial block is nonempty, the output must be at least as long as
522556
// the partial block.

0 commit comments

Comments
 (0)