A little Googling turns up that the author of the Unix library (Xavier, IIRC) provided support for termios(3).  So you can already do what you want in Ocaml with no extra C ugly bits.

Here's a little ocaml program to demonstrate, and after it, some strace output showing the way it calls ioctl(2) to manipulate the line discipline (relevant bits bolded in HTML format mail).

let main () =
  let open Unix in
  let tios = tcgetattr stdin in
  Printf.printf "c_echo: %b\n" tios.c_echo ;
  Printf.printf "c_echoe: %b\n" tios.c_echoe ;
  Printf.printf "c_echok: %b\n" tios.c_echok ;
  Printf.printf "c_echonl: %b\n" tios.c_echonl ;
  flush Pervasives.stdout ;
  tios.c_echo <- false ;
  tcsetattr stdin TCSANOW tios ;
  let tios = tcgetattr stdin in
  Printf.printf "AFTER c_echo: %b\nSleeping 10 sec ....\n" tios.c_echo ;
  flush Pervasives.stdout ;
  Unix.sleep 10;
  tios.c_echo <- true ;
  tcsetattr stdin TCSANOW tios ;
  ()
;;

main() ;;

=====================
$ strace -eioctl ./noecho 
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
c_echo: true
c_echoe: true
c_echok: true
c_echonl: false
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon -echo ...}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon -echo ...}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon -echo ...}) = 0
AFTER c_echo: false
Sleeping 10 sec ....
ioctl(0, TCGETS, {B38400 opost isig icanon -echo ...}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon -echo ...}) = 0
ioctl(0, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
+++ exited with 0 +++