[kernel][entropy] Add cmdlines for jitterentropy
Add a few cmdline-tweakable parameters for the jitterentropy entropy
collector. The cmdlines are used to support MG-1022 (optimizing
jitterentropy's parameter values).
Change-Id: I1d78c49738edf498819097b8f0bc85b1803cf445
diff --git a/docs/kernel_cmdline.md b/docs/kernel_cmdline.md
index cc229c2..14049ab 100644
--- a/docs/kernel_cmdline.md
+++ b/docs/kernel_cmdline.md
@@ -72,7 +72,42 @@
Provides entropy to be mixed into the kernel's CPRNG.
-## kernel.entropy_test.len=\<len>
+## kernel.entropy.jitterentropy.bs=\<num>
+
+Sets the "memory block size" parameter for jitterentropy (the default is 64).
+When jitterentropy is performing memory operations (to increase variation in CPU
+timing), the memory will be accessed in blocks of this size.
+
+## kernel.entropy.jitterentropy.bc=\<num>
+
+Sets the "memory block count" parameter for jitterentropy (the default is 1024).
+When jitterentropy is performing memory operations (to increase variation in CPU
+timing), this controls how many blocks (of size
+`kernel.entropy.jitterentropy.bs`) are accessed.
+
+## kernel.entropy.jitterentropy.ml=\<num>
+
+Sets the "memory loops" parameter for jitterentropy (the default is 128). When
+jitterentropy is performing memory operations (to increase variation in CPU
+timing), this controls how many times the memory access routine is repeated.
+This parameter is only used when `kernel.entropy.jitterentropy.raw` is true
+(otherwise, jitterentropy chooses the number of loops is a random-ish way).
+
+## kernel.entropy.jitterentropy.ll=\<num>
+
+Sets the "LFSR loops" parameter for jitterentropy (the default is 16). When
+jitterentropy is performing CPU-intensive LFSR operations (to increase variation
+in CPU timing), this controls how many times the LFSR routine is repeated. This
+parameter is only used when `kernel.entropy.jitterentropy.raw` is true
+(otherwise, jitterentropy chooses the number of loops is a random-ish way).
+
+## kernel.entropy.jitterentropy.raw=\<bool>
+
+When true, the jitterentropy entropy collector will return raw, unprocessed
+samples. When false (the default), the raw samples will be processed by
+jitterentropy, producing output data that looks closer to uniformly random.
+
+## kernel.entropy\_test.len=\<len>
When running an entropy collector quality test, collect the provided number of
bytes. Defaults to the maximum value `ENTROPY_COLLECTOR_TEST_MAXLEN`.
@@ -80,10 +115,10 @@
The default value for the compile-time constant `ENTROPY_COLLECTOR_TEST_MAXLEN`
is 128 KiB.
-## kernel.entropy_test.src=\<source>
+## kernel.entropy\_test.src=\<source>
When running an entropy collector quality test, use the provided entropy source.
-Currently recognized sources: `hw_rng`.
+Currently recognized sources: `hw_rng`, `jitterentropy`.
## kernel.halt_on_panic=\<bool>
If this option is set (disabled by default), the system will halt on
diff --git a/kernel/lib/crypto/entropy/jitterentropy_collector.cpp b/kernel/lib/crypto/entropy/jitterentropy_collector.cpp
index 87dd522..333dd0b 100644
--- a/kernel/lib/crypto/entropy/jitterentropy_collector.cpp
+++ b/kernel/lib/crypto/entropy/jitterentropy_collector.cpp
@@ -63,14 +63,18 @@
}
JitterentropyCollector::JitterentropyCollector(uint8_t* mem, size_t len)
- : Collector("jitterentropy", /* entropy_per_1000_bytes */ 8000), lock_() {
- // TODO(MG-1022): optimize default jitterentropy parameters
- uint32_t block_size = cmdline_get_uint32("kernel.entropy.jitter.bs", 64);
- uint32_t block_count = cmdline_get_uint32("kernel.entropy.jitter.bc", 1024);
- uint32_t mem_loops = cmdline_get_uint32("kernel.entropy.jitter.ml", 128);
+ : Collector("jitterentropy", /* entropy_per_1000_bytes */ 8000) {
+ // TODO(MG-1022): optimize default jitterentropy parameters, then update
+ // values here and in docs/kernel_cmdline.md.
+ uint32_t bs = cmdline_get_uint32("kernel.entropy.jitterentropy.bs", 64);
+ uint32_t bc = cmdline_get_uint32("kernel.entropy.jitterentropy.bc", 1024);
+ mem_loops_ = cmdline_get_uint32("kernel.entropy.jitterentropy.ml", 128);
+ lfsr_loops_ = cmdline_get_uint32("kernel.entropy.jitterentropy.ll", 16);
+ use_raw_samples_ = cmdline_get_bool("kernel.entropy.jitterentropy.raw",
+ false);
- jent_entropy_collector_init(&ec_, mem, len, block_size, block_count,
- mem_loops, /* stir */ true);
+ jent_entropy_collector_init(&ec_, mem, len, bs, bc, mem_loops_,
+ /* stir */ true);
}
size_t JitterentropyCollector::DrawEntropy(uint8_t* buf, size_t len) {
@@ -79,8 +83,17 @@
// multi-threaded systems.
mxtl::AutoLock guard(&lock_);
- ssize_t result = jent_read_entropy(&ec_, reinterpret_cast<char*>(buf), len);
- return (result < 0) ? 0 : static_cast<size_t>(result);
+ if (use_raw_samples_) {
+ for (size_t i = 0; i < len; i++) {
+ buf[i] = static_cast<uint8_t>(jent_lfsr_var_stat(&ec_, lfsr_loops_,
+ mem_loops_));
+ }
+ return len;
+ } else {
+ ssize_t err =jent_read_entropy(&ec_, reinterpret_cast<char*>(buf),
+ len);
+ return (err < 0) ? 0 : static_cast<size_t>(err);
+ }
}
} // namespace entropy
diff --git a/kernel/lib/crypto/include/lib/crypto/entropy/jitterentropy_collector.h b/kernel/lib/crypto/include/lib/crypto/entropy/jitterentropy_collector.h
index 2037693..74b6824 100644
--- a/kernel/lib/crypto/include/lib/crypto/entropy/jitterentropy_collector.h
+++ b/kernel/lib/crypto/include/lib/crypto/entropy/jitterentropy_collector.h
@@ -53,6 +53,8 @@
struct rand_data ec_;
mxtl::Mutex lock_;
+ uint32_t mem_loops_, lfsr_loops_;
+ bool use_raw_samples_;
};
} // namespace entropy
diff --git a/third_party/lib/jitterentropy/include/lib/jitterentropy/jitterentropy.h b/third_party/lib/jitterentropy/include/lib/jitterentropy/jitterentropy.h
index f3415b0..d4795d3 100644
--- a/third_party/lib/jitterentropy/include/lib/jitterentropy/jitterentropy.h
+++ b/third_party/lib/jitterentropy/include/lib/jitterentropy/jitterentropy.h
@@ -46,6 +46,7 @@
* - Add #include lines for required system libraries.
* - Remove CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT flag.
* - Add jent_entropy_collector_init declaration.
+ * - Moved comment for jent_lfsr_var_stat from jitterentropy-base.c to here.
*/
#ifndef _JITTERENTROPY_H
@@ -148,8 +149,16 @@
/* -- BEGIN statistical test functions only complied with CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT -- */
+/*
+ * Statistical test: return the time duration for the folding operation. If
+ * lfsr_loops_override/mem_loops_override is non-zero, perform the given number
+ * of LFSR/memaccess ops. Otherwise, allow the loop count shuffling to define
+ * the number of LFSR/memaccess ops.
+ */
JENT_PRIVATE_STATIC
-uint64_t jent_lfsr_var_stat(struct rand_data *ec, unsigned int min);
+uint64_t jent_lfsr_var_stat(struct rand_data *ec,
+ unsigned int lfsr_loops_override,
+ unsigned int mem_loops_override);
/* -- END of statistical test function -- */
diff --git a/third_party/lib/jitterentropy/jitterentropy-base.c b/third_party/lib/jitterentropy/jitterentropy-base.c
index 6aaaff2..2aa89e5 100644
--- a/third_party/lib/jitterentropy/jitterentropy-base.c
+++ b/third_party/lib/jitterentropy/jitterentropy-base.c
@@ -57,6 +57,9 @@
* - Remove CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT flag.
* - Add jent_entropy_collector_init definition.
* - Remove '#pragma GCC optimize ("O0")' (not recognized by clang)
+ * - Replace 'min' parameter by 'lfsr_loops_override' and 'mem_loops_override'
+ * in jent_lfsr_var_stat, and moved comment for jent_lfsr_var_stat to
+ * jitterentropy.h.
*/
#undef _FORTIFY_SOURCE
@@ -779,20 +782,17 @@
* Statistical test logic not compiled for regular operation
***************************************************************************/
-/*
- * Statistical test: return the time duration for the folding operation. If min
- * is set, perform the given number of LFSR ops. Otherwise, allow the
- * loop count shuffling to define the number of LFSR ops.
- */
JENT_PRIVATE_STATIC
-uint64_t jent_lfsr_var_stat(struct rand_data *ec, unsigned int min)
+uint64_t jent_lfsr_var_stat(struct rand_data *ec,
+ unsigned int lfsr_loops_override,
+ unsigned int mem_loops_override)
{
uint64_t time = 0;
uint64_t time2 = 0;
jent_get_nstime(&time);
- jent_memaccess(ec, min);
- jent_lfsr_time(ec, time, min);
+ jent_memaccess(ec, mem_loops_override);
+ jent_lfsr_time(ec, time, lfsr_loops_override);
jent_get_nstime(&time2);
return ((time2 - time));
}