/* Provenance: openssl/openssl aes_gcm_siv_initkey (fixed). * repo: openssl/openssl * commit: 609bcb24866d64f1fc49d38b852edbb39057d721 * parent: f87f0b6a8e04bcdeb98afc82b0da06a2d537f399 * commit_url: https://github.com/openssl/openssl/commit/609bcb24866d64f1fc49d38b852edbb39057d721 * cve: CVE-2026-45446 * license: Apache-2.0 * function: aes_gcm_siv_initkey * relpath: providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c */ static int aes_gcm_siv_initkey(void *vctx) { PROV_AES_GCM_SIV_CTX *ctx = (PROV_AES_GCM_SIV_CTX *)vctx; uint8_t output[BLOCK_SIZE]; uint32_t counter = 0x0; size_t i; union { uint32_t counter; uint8_t block[BLOCK_SIZE]; } data; int out_len; EVP_CIPHER *ecb = NULL; DECLARE_IS_ENDIAN; switch (ctx->key_len) { case 16: ecb = EVP_CIPHER_fetch(ctx->libctx, "AES-128-ECB", NULL); break; case 24: ecb = EVP_CIPHER_fetch(ctx->libctx, "AES-192-ECB", NULL); break; case 32: ecb = EVP_CIPHER_fetch(ctx->libctx, "AES-256-ECB", NULL); break; default: goto err; } if (ctx->ecb_ctx == NULL && (ctx->ecb_ctx = EVP_CIPHER_CTX_new()) == NULL) goto err; if (!EVP_EncryptInit_ex2(ctx->ecb_ctx, ecb, ctx->key_gen_key, NULL, NULL)) goto err; memset(&data, 0, sizeof(data)); memcpy(&data.block[sizeof(data.counter)], ctx->nonce, NONCE_SIZE); ctx->generated_tag = 0; memset(ctx->tag, 0, TAG_SIZE); /* msg_auth_key is always 16 bytes in size, regardless of AES128/AES256 */ /* counter is stored little-endian */ for (i = 0; i < BLOCK_SIZE; i += 8) { if (IS_LITTLE_ENDIAN) { data.counter = counter; } else { data.counter = GSWAP4(counter); } /* Block size is 16 (128 bits), but only 8 bytes are used */ out_len = BLOCK_SIZE; if (!EVP_EncryptUpdate(ctx->ecb_ctx, output, &out_len, data.block, BLOCK_SIZE)) goto err; memcpy(&ctx->msg_auth_key[i], output, 8); counter++; } /* msg_enc_key length is directly tied to key length AES128/AES256 */ for (i = 0; i < ctx->key_len; i += 8) { if (IS_LITTLE_ENDIAN) { data.counter = counter; } else { data.counter = GSWAP4(counter); } /* Block size is 16 bytes (128 bits), but only 8 bytes are used */ out_len = BLOCK_SIZE; if (!EVP_EncryptUpdate(ctx->ecb_ctx, output, &out_len, data.block, BLOCK_SIZE)) goto err; memcpy(&ctx->msg_enc_key[i], output, 8); counter++; } if (!EVP_EncryptInit_ex2(ctx->ecb_ctx, ecb, ctx->msg_enc_key, NULL, NULL)) goto err; /* Freshen up the state */ ctx->used_enc = 0; ctx->used_dec = 0; EVP_CIPHER_free(ecb); return 1; err: EVP_CIPHER_CTX_free(ctx->ecb_ctx); EVP_CIPHER_free(ecb); ctx->ecb_ctx = NULL; return 0; }