Rather than think of this as multiplying a frequency, think of measuring one frequency and generating another. A resistive divider is needed for the 12V signal, converting to 5V for a digital input pin. Using micros() to time the gaps between transitions on this pin provides a way to sense frequency.
To generate a frequency you can use a DDS (direct digital synthesis) loop - you update a phase accumulator on a regular basis, like this:
unsigned unsigned int phase_acc = 0 ; // keeps track of phase
unsigned unsigned int phase_inc = 0 ; // amount to increment phase each time
const unsigned int TOP_BIT = 0x8000 ;
unsigned unsigned long update_time = 0 ;
const unsigned long update_period_us = 200; // checking 5000 times a second, good to 2.5kHz output rate.
void set_frequency (float freq) // call when frequency changes.
phase_inc = 65536.0 * freq * update_period_us / 1e6 ;
void handle_dds () // call often, from loop()
if (micros() - update_time > update_period_us)
update_time += update_period_us ; // schedule next check
phase_acc += phase_inc ; // increment phase accumulator
digitalWrite (output_pin, (phase_acc & TOP_BIT) != 0) ; // use top bit as output
The DDS technique can be used for other waveforms by table-lookup if you want, but square waves is easy by just taking the top bit of the phase accumulator. A phase accumulator wraps around every 360 degrees, or in other words is a fixed-point representation of the fractional turn.