Skip to content

crypto: core: Remove ce_aes_ctr_encrypt() to fix AES-GCM compliance - #7833

Merged
jenswikl merged 1 commit into
OP-TEE:masterfrom
MingyenHung:add-ce_aes_gcm_ctr_encrypt-to-support-Inc32
Jun 16, 2026
Merged

crypto: core: Remove ce_aes_ctr_encrypt() to fix AES-GCM compliance#7833
jenswikl merged 1 commit into
OP-TEE:masterfrom
MingyenHung:add-ce_aes_gcm_ctr_encrypt-to-support-Inc32

Conversation

@MingyenHung

Copy link
Copy Markdown
Contributor

AES-GCM (as per NIST SP 800-38D) specifically requires an Inc32 operation. This means only the least significant 32 bits are incremented modulo 2^32, and the increment must not carry over into the upper 96 bits.

Introduce ce_aes_gcm_ctr_encrypt() to implement this behavior instead of using the generic ce_aes_ctr_encrypt().

Add a test case for ARM64 to reproduce this issue
OP-TEE/optee_test#817

Comment thread core/arch/arm/crypto/aes-gcm-ce.c Outdated
while (num_blocks) {
pmull_ghash_update(1, dg, src, &state->ghash_key, NULL);
ce_aes_ctr_encrypt(dst, src, (const uint8_t *)ek->data,
ce_aes_gcm_ctr_encrypt(dst, src, (const uint8_t *)ek->data,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Aarch64, update_payload_2block() does the heavy lifting, and this function is only called for a single block. We could replace the ce_aes_ctr_encrypt() call with the counterpart of what's done in encrypt_pl() without noticeable impact on the performance.

The drawback is that for Aarch32 (still on Armv8-A hardware), we'd get slightly slower performance. But we're still processing block by block, so it can't be that great to start with.

Do we care enough about Aarch32 to duplicate the two assembly functions ce_aes_ctr_encrypt()? If yes, please rename ce_aes_gcm_ctr_encrypt() to ce_aes_ctr_inc32_encrypt() and see if it can be refactored together with ce_aes_ctr_encrypt() to avoid some duplicated code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced ce_aes_ctr_encrypt() with the counterpart of what's done in encrypt_pl().

@MingyenHung
MingyenHung force-pushed the add-ce_aes_gcm_ctr_encrypt-to-support-Inc32 branch 2 times, most recently from 6b59804 to bd1a59f Compare June 10, 2026 10:43
@MingyenHung MingyenHung changed the title core: crypto: Add ce_aes_gcm_ctr_encrypt to support Inc32 crypto: core: Remove ce_aes_ctr_encrypt() to fix AES-GCM compliance Jun 10, 2026
Comment thread core/arch/arm/crypto/aes-gcm-ce.c Outdated
ek->rounds, 1, (uint8_t *)state->ctr, 1);

ce_aes_ecb_encrypt(buf_cryp, (const uint8_t *)state->ctr,
(const uint8_t *)ek->data, ek->rounds,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please align with the opening ( on the row above.

Comment thread core/arch/arm/crypto/aes-gcm-ce.c Outdated
1, 1);
internal_aes_gcm_inc_ctr(state);

ce_aes_xor_block(dst, buf_cryp, src);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit concerned that we read src twice. I don't know whether it can be exploited right now, but I'd like to protect against this scenario:
src is untrusted memory and can be updated by an untrusted CPU, but dst is in trusted memory and can only be updated by trusted CPUs. What if the untrusted CPU updates the src content after the GHASH stage, so something else is decrypted? We'd think that dst is alright since the tag is correct.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please review the new patchset d686b25 and check whether it meets the requirements.

@MingyenHung
MingyenHung force-pushed the add-ce_aes_gcm_ctr_encrypt-to-support-Inc32 branch from bd1a59f to d686b25 Compare June 12, 2026 08:24
Comment thread core/arch/arm/crypto/aes-gcm-ce.c Outdated
pmull_ghash_update(1, dg, src, &state->ghash_key, NULL);
ce_aes_ctr_encrypt(dst, src, (const uint8_t *)ek->data,
ek->rounds, 1, (uint8_t *)state->ctr, 1);
/* Copy from untrusted memory 'src' into a temporary buffer

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/*
 * Please format multi-
 * line comments like
 * this.
 */

Comment thread core/arch/arm/crypto/aes-gcm-ce.c Outdated
const uint8_t *src, size_t num_blocks, uint8_t *dst)
{
void *buf_cryp = state->buf_cryp;
uint8_t src_tmp[TEE_AES_BLOCK_SIZE];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coding guidelines (https://optee.readthedocs.io/en/latest/general/coding_standards.html) require this to be initialized.

@MingyenHung
MingyenHung force-pushed the add-ce_aes_gcm_ctr_encrypt-to-support-Inc32 branch from d686b25 to 614221d Compare June 16, 2026 07:14
@jenswikl

Copy link
Copy Markdown
Contributor

Looks good, please apply:
Reviewed-by: Jens Wiklander <jenswi@kernel.org>

AES-GCM (per NIST SP 800-38D) requires the Inc32 operation for the counter,
meaning only the least significant 32 bits are incremented modulo 2^32,
and the increment must not carry over into the upper 96 bits.

However, ce_aes_ctr_encrypt() performs a full 128-bit increment, making it
unsuitable for AES-GCM. Remove ce_aes_ctr_encrypt() and replace its usage
with a compliant counter increment implementation.

Signed-off-by: Mingyen Hung <mingyen.hung@amlogic.com>
Reviewed-by: Jens Wiklander <jenswi@kernel.org>
@MingyenHung
MingyenHung force-pushed the add-ce_aes_gcm_ctr_encrypt-to-support-Inc32 branch from 614221d to c93b585 Compare June 16, 2026 07:46
@jenswikl

Copy link
Copy Markdown
Contributor

I'm waiting for CI tests to pass before merging this.

@jenswikl
jenswikl merged commit a038305 into OP-TEE:master Jun 16, 2026
57 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants