Use readatleast instead of reimplementing it

use `io.ReadAtLeast` instead of reimplementing it

This also returns the correct error (io.UnexpectedEOF), if we didn't get what we want.

It made no difference to the callers -- which I audited down to packets.go -- where we convert any error from this path to `driver.ErrBadConn` so the propagation of this new error stops in packets.go.

Future enhancements can now differentiate between the EOF situation after we got what we want and before we could read a complete packet.