Added env-var 'MLOCK_SECRETS' to disable memory locks.
This commit is contained in:
parent
8f6dce18f2
commit
69ff326430
|
@ -15,6 +15,7 @@ byteorder = "1.2.3"
|
|||
errno = "0.2.4"
|
||||
failure = "0.1"
|
||||
init_with = "1.1.0"
|
||||
lazy_static = "1.1.0"
|
||||
log = "0.4.1"
|
||||
memsec = "0.5.4"
|
||||
pairing = { version = "0.14.2", features = ["u128-support"] }
|
||||
|
|
28
src/lib.rs
28
src/lib.rs
|
@ -10,6 +10,8 @@ extern crate errno;
|
|||
extern crate failure;
|
||||
extern crate init_with;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate memsec;
|
||||
extern crate pairing;
|
||||
|
@ -26,6 +28,7 @@ mod into_fr;
|
|||
pub mod poly;
|
||||
pub mod serde_impl;
|
||||
|
||||
use std::env;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::mem::size_of_val;
|
||||
|
@ -37,13 +40,30 @@ use init_with::InitWith;
|
|||
use memsec::{memzero, mlock, munlock};
|
||||
use pairing::bls12_381::{Bls12, Fr, G1, G1Affine, G2, G2Affine};
|
||||
use pairing::{CurveAffine, CurveProjective, Engine, Field};
|
||||
use rand::{ChaChaRng, OsRng, Rng, Rand, SeedableRng};
|
||||
use rand::{ChaChaRng, OsRng, Rand, Rng, SeedableRng};
|
||||
use tiny_keccak::sha3_256;
|
||||
|
||||
use error::{Error, Result};
|
||||
use into_fr::IntoFr;
|
||||
use poly::{Commitment, Poly};
|
||||
|
||||
lazy_static! {
|
||||
// Sets whether or not `mlock`ing is enabled. Memory locking is enabled by default; it can be
|
||||
// disabled by setting the environment variable `MLOCK_SECRETS=false`. This is useful when you
|
||||
// are running on a system where you do not have the ability to increase the systems locked
|
||||
// memory limit (which can be found using the Unix command: `ulimit -l`). For example, we
|
||||
// disable `mlock`ing of secrets when testing crates that depend on `threshold_crypto` when
|
||||
// running in Travis CI because Travis has a locked memory limit of 64kb, which we may exceed
|
||||
// while running `cargo test`. Disabling `mlock`ing for secret values allows secret keys to be
|
||||
// swapped/core-dumped to disk, resulting in unmanaged copies of secrets to hang around in
|
||||
// memory; this is significantly less secure than enabling memory locking (the default). Only
|
||||
// set `MLOCK_SECRETS=false` in development/testing.
|
||||
pub(crate) static ref SHOULD_MLOCK_SECRETS: bool = match env::var("MLOCK_SECRETS") {
|
||||
Ok(s) => s.parse().unwrap_or(true),
|
||||
_ => true,
|
||||
};
|
||||
}
|
||||
|
||||
/// Marks a type as containing one or more secret prime field elements.
|
||||
pub(crate) trait ContainsSecret {
|
||||
/// Calls the `mlock` system call on the region of memory allocated for the secret prime field
|
||||
|
@ -299,6 +319,9 @@ impl fmt::Debug for SecretKey {
|
|||
|
||||
impl ContainsSecret for SecretKey {
|
||||
fn mlock_secret_memory(&self) -> Result<()> {
|
||||
if !*SHOULD_MLOCK_SECRETS {
|
||||
return Ok(());
|
||||
}
|
||||
let ptr = &*self.0 as *const Fr as *mut u8;
|
||||
let n_bytes = size_of_val(&*self.0);
|
||||
let mlock_succeeded = unsafe { mlock(ptr, n_bytes) };
|
||||
|
@ -315,6 +338,9 @@ impl ContainsSecret for SecretKey {
|
|||
}
|
||||
|
||||
fn munlock_secret_memory(&self) -> Result<()> {
|
||||
if !*SHOULD_MLOCK_SECRETS {
|
||||
return Ok(());
|
||||
}
|
||||
let ptr = &*self.0 as *const Fr as *mut u8;
|
||||
let n_bytes = size_of_val(&*self.0);
|
||||
let munlock_succeeded = unsafe { munlock(ptr, n_bytes) };
|
||||
|
|
20
src/poly.rs
20
src/poly.rs
|
@ -28,7 +28,7 @@ use pairing::bls12_381::{Fr, G1, G1Affine};
|
|||
use pairing::{CurveAffine, CurveProjective, Field};
|
||||
use rand::Rng;
|
||||
|
||||
use super::{ContainsSecret, Error, IntoFr, Result};
|
||||
use super::{ContainsSecret, Error, IntoFr, Result, SHOULD_MLOCK_SECRETS};
|
||||
|
||||
/// A univariate polynomial in the prime field.
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq)]
|
||||
|
@ -288,6 +288,9 @@ impl Drop for Poly {
|
|||
|
||||
impl ContainsSecret for Poly {
|
||||
fn mlock_secret_memory(&self) -> Result<()> {
|
||||
if !*SHOULD_MLOCK_SECRETS {
|
||||
return Ok(());
|
||||
}
|
||||
let ptr = self.coeff.as_ptr() as *mut u8;
|
||||
let n_bytes = size_of_val(self.coeff.as_slice());
|
||||
if n_bytes == 0 {
|
||||
|
@ -307,6 +310,9 @@ impl ContainsSecret for Poly {
|
|||
}
|
||||
|
||||
fn munlock_secret_memory(&self) -> Result<()> {
|
||||
if !*SHOULD_MLOCK_SECRETS {
|
||||
return Ok(());
|
||||
}
|
||||
let ptr = self.coeff.as_ptr() as *mut u8;
|
||||
let n_bytes = size_of_val(self.coeff.as_slice());
|
||||
if n_bytes == 0 {
|
||||
|
@ -510,6 +516,9 @@ impl Poly {
|
|||
|
||||
// Removes the `mlock` for `len` elements that have been truncated from the `coeff` vector.
|
||||
fn truncate_mlock(&self, len: usize) -> Result<()> {
|
||||
if !*SHOULD_MLOCK_SECRETS {
|
||||
return Ok(());
|
||||
}
|
||||
let n_bytes_truncated = len * size_of::<Fr>();
|
||||
if n_bytes_truncated == 0 {
|
||||
return Ok(());
|
||||
|
@ -532,6 +541,9 @@ impl Poly {
|
|||
|
||||
// Extends the `mlock` on the `coeff` vector when `len` new elements are added.
|
||||
fn extend_mlock(&self, len: usize) -> Result<()> {
|
||||
if !*SHOULD_MLOCK_SECRETS {
|
||||
return Ok(());
|
||||
}
|
||||
let n_bytes_extended = len * size_of::<Fr>();
|
||||
if n_bytes_extended == 0 {
|
||||
return Ok(());
|
||||
|
@ -684,6 +696,9 @@ impl Debug for BivarPoly {
|
|||
|
||||
impl ContainsSecret for BivarPoly {
|
||||
fn mlock_secret_memory(&self) -> Result<()> {
|
||||
if !*SHOULD_MLOCK_SECRETS {
|
||||
return Ok(());
|
||||
}
|
||||
let ptr = self.coeff.as_ptr() as *mut u8;
|
||||
let n_bytes = size_of_val(self.coeff.as_slice());
|
||||
if n_bytes == 0 {
|
||||
|
@ -703,6 +718,9 @@ impl ContainsSecret for BivarPoly {
|
|||
}
|
||||
|
||||
fn munlock_secret_memory(&self) -> Result<()> {
|
||||
if !*SHOULD_MLOCK_SECRETS {
|
||||
return Ok(());
|
||||
}
|
||||
let ptr = self.coeff.as_ptr() as *mut u8;
|
||||
let n_bytes = size_of_val(self.coeff.as_slice());
|
||||
if n_bytes == 0 {
|
||||
|
|
Loading…
Reference in New Issue