Added env-var 'MLOCK_SECRETS' to disable memory locks.

This commit is contained in:
DrPeterVanNostrand 2018-08-08 15:49:55 +00:00
parent 8f6dce18f2
commit 69ff326430
3 changed files with 47 additions and 2 deletions

View File

@ -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"] }

View File

@ -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) };

View File

@ -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 {