std::vector OsslGcmWrapper::Encrypt()

in azure-protected-vm-secrets/Linux/OsslAesWrapper.cpp [65:103]


std::vector<unsigned char> OsslGcmWrapper::Encrypt(const std::vector<unsigned char> &data, AesChainingInfo* chainingInfo) const {
    if (!chainingInfo) {
        throw std::runtime_error("Chaining info must be set before calling Encrypt");
    }

    if (EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), nullptr, nullptr, nullptr) != 1) {
        throw OsslError(ERR_get_error(), "Failed to initialize encryption");
    }

    if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, chainingInfo->GetInitVector().size(), nullptr) != 1) {
        throw OsslError(ERR_get_error(), "Failed to set IV length");
    }

    if (EVP_EncryptInit_ex(ctx, nullptr, nullptr, key.data(), chainingInfo->GetInitVector().data()) != 1) {
        throw OsslError(ERR_get_error(), "Failed to set key and IV");
    }

    std::vector<unsigned char> ciphertext(data.size() + EVP_MAX_BLOCK_LENGTH);
    int len = 0, ciphertext_len = 0;

    if (EVP_EncryptUpdate(ctx, ciphertext.data(), &len, data.data(), data.size()) != 1) {
        throw OsslError(ERR_get_error(), "Failed to encrypt");
    }
    ciphertext_len = len;

    if (EVP_EncryptFinal_ex(ctx, ciphertext.data() + len, &len) != 1) {
        throw OsslError(ERR_get_error(), "Failed to finalize encryption");
    }
    ciphertext_len += len;

    std::vector<unsigned char> tag(16);
    if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, tag.size(), tag.data()) != 1) {
        throw OsslError(ERR_get_error(), "Failed to get tag");
    }

    ciphertext.resize(ciphertext_len);
    ciphertext.insert(ciphertext.end(), tag.begin(), tag.end());
    return ciphertext;
}