You do not need the [[ ... ]]. Simply rewrite it as:
#!/bin/bash
if read -t 10 -sp "Enter Password: " passwd; then
echo -e "\nPassword: ${passwd}"
else
echo -e "\nInput timed out" >&2
exit 1
fi
exit 0
or to be easier to read and/or shorter:
#!/bin/bash
read -t 10 -sp "Enter Password: " passwd || echo -e "\nInput timed out" >&2 && exit 1
echo -e "\nPassword: ${passwd}"
exit 0
Update:
To understand why it works without [[ ... ]], the bash man must be checked:
if list; then list; [ elif list; then list; ] ... [ else list; ] fi
The if list is executed. If its exit status is zero, the then list is executed. Otherwise, each elif list is executed in turn, [...]
In this case, The if list is the read command. [ $? -eq 0 ] and test $? -eq 0 are also valid lists with specific exit status. [[ expression ]] (again according to bash's man) is also a valid list, but read -t 10 -sp "Enter Password: " passwd is not a valid expression. See the man to know what are valid expressions.