If setup fails, hang forever
Without this init will repeatedly try to start this daemon,
causing logspam.
Also:
* wait until just before tokio conversion to set O_NONBLOCK
* ensure logging code reflects source example
* log at info and higher
* use contexts for better logging
* fall back to println to work around logging problems
* remove wrong copy-pasted comment in Android.bp
Bug: 249531229
Fixes: 249566340
Test: in permissive mode, rm /dev/hw_random before start
Change-Id: Ib70cbcb048f33dca789151622d98c6d56270fa37
diff --git a/prng_seeder/src/conditioner.rs b/prng_seeder/src/conditioner.rs
index 66b29a4..eca8af8 100644
--- a/prng_seeder/src/conditioner.rs
+++ b/prng_seeder/src/conditioner.rs
@@ -12,10 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-use std::{fs::File, io::Read};
+use std::{fs::File, io::Read, os::unix::io::AsRawFd};
-use anyhow::{ensure, Result};
+use anyhow::{ensure, Context, Result};
use log::debug;
+use nix::fcntl::{fcntl, FcntlArg::F_SETFL, OFlag};
use tokio::io::AsyncReadExt;
use crate::drbg;
@@ -23,6 +24,30 @@
const SEED_FOR_CLIENT_LEN: usize = 496;
const NUM_REQUESTS_PER_RESEED: u32 = 256;
+pub struct ConditionerBuilder {
+ hwrng: File,
+ rg: drbg::Drbg,
+}
+
+impl ConditionerBuilder {
+ pub fn new(mut hwrng: File) -> Result<ConditionerBuilder> {
+ let mut et: drbg::Entropy = [0; drbg::ENTROPY_LEN];
+ hwrng.read_exact(&mut et).context("hwrng.read_exact in new")?;
+ let rg = drbg::Drbg::new(&et)?;
+ fcntl(hwrng.as_raw_fd(), F_SETFL(OFlag::O_NONBLOCK))
+ .context("setting O_NONBLOCK on hwrng")?;
+ Ok(ConditionerBuilder { hwrng, rg })
+ }
+
+ pub fn build(self) -> Conditioner {
+ Conditioner {
+ hwrng: tokio::fs::File::from_std(self.hwrng),
+ rg: self.rg,
+ requests_since_reseed: 0,
+ }
+ }
+}
+
pub struct Conditioner {
hwrng: tokio::fs::File,
rg: drbg::Drbg,
@@ -30,18 +55,11 @@
}
impl Conditioner {
- pub fn new(mut hwrng: File) -> Result<Conditioner> {
- let mut et: drbg::Entropy = [0; drbg::ENTROPY_LEN];
- hwrng.read_exact(&mut et)?;
- let rg = drbg::Drbg::new(&et)?;
- Ok(Conditioner { hwrng: tokio::fs::File::from_std(hwrng), rg, requests_since_reseed: 0 })
- }
-
pub async fn reseed_if_necessary(&mut self) -> Result<()> {
if self.requests_since_reseed >= NUM_REQUESTS_PER_RESEED {
debug!("Reseeding DRBG");
let mut et: drbg::Entropy = [0; drbg::ENTROPY_LEN];
- self.hwrng.read_exact(&mut et).await?;
+ self.hwrng.read_exact(&mut et).await.context("hwrng.read_exact in reseed")?;
self.rg.reseed(&et)?;
self.requests_since_reseed = 0;
}