blob: 3b154bd8f14e7279d64e2aebed92bbfff4dede8f [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! Cryptography in Rust.
#![deny(missing_docs)]
#![deny(warnings)]
// just in case we forget to add #[forbid(unsafe_code)] on new module
// definitions
#![deny(unsafe_code)]
extern crate boringssl_sys;
extern crate failure;
// Forbid unsafe code except in the boringssl module.
#[allow(unsafe_code)]
mod boringssl;
#[forbid(unsafe_code)]
pub mod hash;
#[forbid(unsafe_code)]
pub mod hmac;
#[forbid(unsafe_code)]
pub mod insecure;
#[forbid(unsafe_code)]
pub mod kdf;
#[forbid(unsafe_code)]
pub mod password;
#[forbid(unsafe_code)]
pub mod public;
#[forbid(unsafe_code)]
mod util;
use std::fmt::{self, Debug, Display, Formatter};
use failure::Fail;
use boringssl::BoringError;
/// Reads cryptographically-secure random bytes.
///
/// This is a low-level primitive often used to construct higher-level
/// protocols. Unless you're sure that this is what you need, you should
/// probably be using something else. For example, all key types can be randomly
/// generated using higher-level functions (e.g., [`EcPrivKey::generate`]),
/// scrypt nonces are generated using the [`scrypt_generate`] function, etc.
///
/// [`EcPrivKey::generate`]: ::public::ec::EcPrivKey::generate
/// [`scrypt_generate`]: ::password::scrypt::scrypt_generate
pub fn rand_bytes(bytes: &mut [u8]) {
boringssl::rand_bytes(bytes);
}
/// Errors generated by this crate.
///
/// `Error` represents two types of errors: errors generated by BoringSSL, and
/// errors generated by the Rust code in this crate. When printed (using either
/// `Display` or `Debug`), BoringSSL errors are of the form `boring: <error>`,
/// while errors generated by Rust code are of the form `mundane: <error>`.
pub struct Error(ErrorInner);
impl Error {
fn new(s: String) -> Error {
Error(ErrorInner::Mundane(s))
}
}
impl From<BoringError> for Error {
fn from(err: BoringError) -> Error {
Error(ErrorInner::Boring(err))
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
match &self.0 {
ErrorInner::Mundane(err) => write!(f, "mundane: {}", err),
ErrorInner::Boring(err) => write!(f, "boring: {}", err),
}
}
}
impl Debug for Error {
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
match &self.0 {
ErrorInner::Mundane(err) => write!(f, "mundane: {}", err),
ErrorInner::Boring(err) => {
if err.stack_depth() == 1 {
// Either there was no stack trace, or the stack trace only
// contained a single frame. In either case, don't bother
// printing a preceding newline.
write!(f, "boring: {:?}", err)
} else {
// There's a multi-line stack trace, so print a preceding
// newline.
write!(f, "boring:\n{:?}", err)
}
}
}
}
}
impl Fail for Error {}
enum ErrorInner {
Mundane(String),
Boring(BoringError),
}