Hi, thank you for taking the time to reply.
I added attribute noinline to the function generating the key schedule, aesni_setkey_enc_128() and rebuilt. However, it is still only called twice in total. I also added a breakpoint in aes.c:547, which looks like the non AES-NI code to generate the key schedule? That was never called.
My ciphersuite is TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256, according to mbedtls_ssl_get_ciphersuite(mbedtls_ssl_context).
Besides adding break points I have also stepped through the code, line by line. Please correct me if my understanding is wrong here:
mbedtls_ssl_decrypt_buf() extracts the 4 byte salt, which is stored within transform->iv_dec? mbedtls_ssl_decrypt_buf() also sets the 8 byte explicit_nonce to variable dynamic_iv? The same function then passes these two variables to ssl_build_record_nonce(), which creates the 12-byte IV?
Eventually we reach mbedtls_gcm_crypt_and_tag(), which calls mbedtls_gcm_starts()
mbedtls_gcm_starts() copies the 12 byte IV in to a 16 byte within mbedtls_gcm_context->y and increments by 1. This is the IV value required to generate the key schedule of the first block of ciphertext.
The remaining call stack to the point of decryption is:
mbedtls_gcm_starts() mbedtls_cipher_update() ctx->cipher_info->base->ecb_func() aes_crypt_ecb_wrap() mbedtls_aes_crypt_ecb() mbedtls_aesni_crypt_ecb()
mbedtls_aesni_crypt_ecb() loads the round key via (ctx->buf + ctx->rk_offset) to decrypt the first block of ciphertext.
However, I could not see any of this path calling a function which generated a key schedule.
I must be wrong (because it works) but if you could show where it is happening, that would be greatly appreciated.
Just to repeat (in case my understanding is wrong) I am expecting 11 keys to be generated before every block of 16 bytes is decrypted.