Bug 1806766 - Update rand_core to 0.6.4. r=emilio,supply-chain-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D165510
This commit is contained in:
Mike Hommey 2022-12-27 05:07:30 +00:00
Родитель 1e26a73a6b
Коммит 30676e53f8
10 изменённых файлов: 245 добавлений и 76 удалений

4
Cargo.lock сгенерированный
Просмотреть файл

@ -4410,9 +4410,9 @@ dependencies = [
[[package]]
name = "rand_core"
version = "0.6.3"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]

Просмотреть файл

@ -1422,6 +1422,11 @@ The core logic is very simple, and acts as an abstraction trait for `Cell<T>`
and `AtomicT`.
"""
[[audits.rand_core]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "0.6.3 -> 0.6.4"
[[audits.raw-window-handle]]
who = "Jim Blandy <jimb@red-bean.com>"
criteria = "safe-to-deploy"

Просмотреть файл

@ -1 +1 @@
{"files":{"CHANGELOG.md":"25e64e1e95a61d0ba0eb476b3512cdacec6e64cbad44e560678efa16242ea291","COPYRIGHT":"90eb64f0279b0d9432accfa6023ff803bc4965212383697eee27a0f426d5f8d5","Cargo.toml":"262864cafee79bee4b22c53f4ba25bb938bab7e96495042241242e3472ba0262","LICENSE-APACHE":"aaff376532ea30a0cd5330b9502ad4a4c8bf769c539c87ffe78819d188a18ebf","LICENSE-MIT":"209fbbe0ad52d9235e37badf9cadfe4dbdc87203179c0899e738b39ade42177b","README.md":"bb3bd3831adc9eaabbcea108ab7f02f5837e9d2f81e872ffd7d340ad466df4de","src/block.rs":"724d13d7721396b46c18999231823c3ea9f6736492102c7c05ee057606372c39","src/error.rs":"0b6d5a188a256fa367dfa368e7dd846b58977a957489c03902307eb78ce4c9e8","src/impls.rs":"d6a97255d92c06bdd1a54590648bbe4cfb41111ac9e761496baf6b7eb5e92f6a","src/le.rs":"f302239d09cc8d915aa8d4fe46c32c8981900cb20d42b12eef9c34e2e820bc88","src/lib.rs":"8b17ae9af2eb43c28320a87893cb234c3889b4dd6246899bbc11e310ce142fa6","src/os.rs":"47849479e19c43dd01259eb14be7b4daf8474d23567dc32a1547c10b108b7069"},"package":"d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"}
{"files":{"CHANGELOG.md":"a33a4318dd822ef757ec79c5e6027d50d9feee5c40f85d9aadf0f598eb7ef1b7","COPYRIGHT":"90eb64f0279b0d9432accfa6023ff803bc4965212383697eee27a0f426d5f8d5","Cargo.toml":"4a6762f8364d1a60f1436f4ba7d710de22465722340d2028101fcbd68e89396f","LICENSE-APACHE":"6df43f6f4b5d4587f3d8d71e45532c688fd168afa5fe89d571cb32fa09c4ef51","LICENSE-MIT":"209fbbe0ad52d9235e37badf9cadfe4dbdc87203179c0899e738b39ade42177b","README.md":"bb3bd3831adc9eaabbcea108ab7f02f5837e9d2f81e872ffd7d340ad466df4de","src/block.rs":"c0b606dc404a1f4b25eebf388e9c0da583ee571214cdcb0bac1b592450d6b4fa","src/error.rs":"c34af905a9ffbae65970f508a9e74480b56747128d05ad350475150898fc6452","src/impls.rs":"b861532f8a3500de6bd0e926b3677a15261df4b12d253e4a8fd6acc5e64f1d36","src/le.rs":"f302239d09cc8d915aa8d4fe46c32c8981900cb20d42b12eef9c34e2e820bc88","src/lib.rs":"df270489b859465fce144098d5e709b318d9f3b703a92f4a28e5f74334119107","src/os.rs":"47849479e19c43dd01259eb14be7b4daf8474d23567dc32a1547c10b108b7069"},"package":"ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"}

5
third_party/rust/rand_core/CHANGELOG.md поставляемый
Просмотреть файл

@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.6.4] - 2022-09-15
- Fix unsoundness in `<BlockRng64 as RngCore>::next_u32` (#1160)
- Reduce use of `unsafe` and improve gen_bytes performance (#1180)
- Add `CryptoRngCore` trait (#1187, #1230)
## [0.6.3] - 2021-06-15
### Changed
- Improved bound for `serde` impls on `BlockRng` (#1130)

43
third_party/rust/rand_core/Cargo.toml поставляемый
Просмотреть файл

@ -3,32 +3,47 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
name = "rand_core"
version = "0.6.3"
authors = ["The Rand Project Developers", "The Rust Project Developers"]
description = "Core random number generator traits and tools for implementation.\n"
version = "0.6.4"
authors = [
"The Rand Project Developers",
"The Rust Project Developers",
]
description = """
Core random number generator traits and tools for implementation.
"""
homepage = "https://rust-random.github.io/book"
documentation = "https://docs.rs/rand_core"
readme = "README.md"
keywords = ["random", "rng"]
categories = ["algorithms", "no-std"]
keywords = [
"random",
"rng",
]
categories = [
"algorithms",
"no-std",
]
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-random/rand"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "doc_cfg"]
rustdoc-args = [
"--cfg",
"doc_cfg",
]
[package.metadata.playground]
all-features = true
[dependencies.getrandom]
version = "0.2"
optional = true
@ -41,4 +56,8 @@ optional = true
[features]
alloc = []
serde1 = ["serde"]
std = ["alloc", "getrandom", "getrandom/std"]
std = [
"alloc",
"getrandom",
"getrandom/std",
]

14
third_party/rust/rand_core/LICENSE-APACHE поставляемый
Просмотреть файл

@ -185,17 +185,3 @@ APPENDIX: How to apply the Apache License to your work.
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

128
third_party/rust/rand_core/src/block.rs поставляемый
Просмотреть файл

@ -95,7 +95,7 @@ pub trait BlockRngCore {
/// [`fill_bytes`] / [`try_fill_bytes`] is called on a large array. These methods
/// also handle the bookkeeping of when to generate a new batch of values.
///
/// No whole generated `u32` values are thown away and all values are consumed
/// No whole generated `u32` values are thrown away and all values are consumed
/// in-order. [`next_u32`] simply takes the next available `u32` value.
/// [`next_u64`] is implemented by combining two `u32` values, least
/// significant first. [`fill_bytes`] and [`try_fill_bytes`] consume a whole
@ -352,27 +352,21 @@ where
{
#[inline]
fn next_u32(&mut self) -> u32 {
let mut index = self.index * 2 - self.half_used as usize;
if index >= self.results.as_ref().len() * 2 {
let mut index = self.index - self.half_used as usize;
if index >= self.results.as_ref().len() {
self.core.generate(&mut self.results);
self.index = 0;
index = 0;
// `self.half_used` is by definition `false`
self.half_used = false;
index = 0;
}
let shift = 32 * (self.half_used as usize);
self.half_used = !self.half_used;
self.index += self.half_used as usize;
// Index as if this is a u32 slice.
unsafe {
let results = &*(self.results.as_ref() as *const [u64] as *const [u32]);
if cfg!(target_endian = "little") {
*results.get_unchecked(index)
} else {
*results.get_unchecked(index ^ 1)
}
}
(self.results.as_ref()[index] >> shift) as u32
}
#[inline]
@ -435,3 +429,111 @@ impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng64<R> {
}
impl<R: BlockRngCore + CryptoRng> CryptoRng for BlockRng<R> {}
#[cfg(test)]
mod test {
use crate::{SeedableRng, RngCore};
use crate::block::{BlockRng, BlockRng64, BlockRngCore};
#[derive(Debug, Clone)]
struct DummyRng {
counter: u32,
}
impl BlockRngCore for DummyRng {
type Item = u32;
type Results = [u32; 16];
fn generate(&mut self, results: &mut Self::Results) {
for r in results {
*r = self.counter;
self.counter = self.counter.wrapping_add(3511615421);
}
}
}
impl SeedableRng for DummyRng {
type Seed = [u8; 4];
fn from_seed(seed: Self::Seed) -> Self {
DummyRng { counter: u32::from_le_bytes(seed) }
}
}
#[test]
fn blockrng_next_u32_vs_next_u64() {
let mut rng1 = BlockRng::<DummyRng>::from_seed([1, 2, 3, 4]);
let mut rng2 = rng1.clone();
let mut rng3 = rng1.clone();
let mut a = [0; 16];
(&mut a[..4]).copy_from_slice(&rng1.next_u32().to_le_bytes());
(&mut a[4..12]).copy_from_slice(&rng1.next_u64().to_le_bytes());
(&mut a[12..]).copy_from_slice(&rng1.next_u32().to_le_bytes());
let mut b = [0; 16];
(&mut b[..4]).copy_from_slice(&rng2.next_u32().to_le_bytes());
(&mut b[4..8]).copy_from_slice(&rng2.next_u32().to_le_bytes());
(&mut b[8..]).copy_from_slice(&rng2.next_u64().to_le_bytes());
assert_eq!(a, b);
let mut c = [0; 16];
(&mut c[..8]).copy_from_slice(&rng3.next_u64().to_le_bytes());
(&mut c[8..12]).copy_from_slice(&rng3.next_u32().to_le_bytes());
(&mut c[12..]).copy_from_slice(&rng3.next_u32().to_le_bytes());
assert_eq!(a, c);
}
#[derive(Debug, Clone)]
struct DummyRng64 {
counter: u64,
}
impl BlockRngCore for DummyRng64 {
type Item = u64;
type Results = [u64; 8];
fn generate(&mut self, results: &mut Self::Results) {
for r in results {
*r = self.counter;
self.counter = self.counter.wrapping_add(2781463553396133981);
}
}
}
impl SeedableRng for DummyRng64 {
type Seed = [u8; 8];
fn from_seed(seed: Self::Seed) -> Self {
DummyRng64 { counter: u64::from_le_bytes(seed) }
}
}
#[test]
fn blockrng64_next_u32_vs_next_u64() {
let mut rng1 = BlockRng64::<DummyRng64>::from_seed([1, 2, 3, 4, 5, 6, 7, 8]);
let mut rng2 = rng1.clone();
let mut rng3 = rng1.clone();
let mut a = [0; 16];
(&mut a[..4]).copy_from_slice(&rng1.next_u32().to_le_bytes());
(&mut a[4..12]).copy_from_slice(&rng1.next_u64().to_le_bytes());
(&mut a[12..]).copy_from_slice(&rng1.next_u32().to_le_bytes());
let mut b = [0; 16];
(&mut b[..4]).copy_from_slice(&rng2.next_u32().to_le_bytes());
(&mut b[4..8]).copy_from_slice(&rng2.next_u32().to_le_bytes());
(&mut b[8..]).copy_from_slice(&rng2.next_u64().to_le_bytes());
assert_ne!(a, b);
assert_eq!(&a[..4], &b[..4]);
assert_eq!(&a[4..12], &b[8..]);
let mut c = [0; 16];
(&mut c[..8]).copy_from_slice(&rng3.next_u64().to_le_bytes());
(&mut c[8..12]).copy_from_slice(&rng3.next_u32().to_le_bytes());
(&mut c[12..]).copy_from_slice(&rng3.next_u32().to_le_bytes());
assert_eq!(b, c);
}
}

2
third_party/rust/rand_core/src/error.rs поставляемый
Просмотреть файл

@ -82,7 +82,7 @@ impl Error {
///
/// This method is identical to `std::io::Error::raw_os_error()`, except
/// that it works in `no_std` contexts. If this method returns `None`, the
/// error value can still be formatted via the `Diplay` implementation.
/// error value can still be formatted via the `Display` implementation.
#[inline]
pub fn raw_os_error(&self) -> Option<i32> {
#[cfg(feature = "std")]

81
third_party/rust/rand_core/src/impls.rs поставляемый
Просмотреть файл

@ -52,36 +52,59 @@ pub fn fill_bytes_via_next<R: RngCore + ?Sized>(rng: &mut R, dest: &mut [u8]) {
}
}
macro_rules! fill_via_chunks {
($src:expr, $dst:expr, $ty:ty) => {{
const SIZE: usize = core::mem::size_of::<$ty>();
let chunk_size_u8 = min($src.len() * SIZE, $dst.len());
let chunk_size = (chunk_size_u8 + SIZE - 1) / SIZE;
trait Observable: Copy {
type Bytes: AsRef<[u8]>;
fn to_le_bytes(self) -> Self::Bytes;
// The following can be replaced with safe code, but unfortunately it's
// ca. 8% slower.
if cfg!(target_endian = "little") {
unsafe {
core::ptr::copy_nonoverlapping(
$src.as_ptr() as *const u8,
$dst.as_mut_ptr(),
chunk_size_u8);
}
} else {
for (&n, chunk) in $src.iter().zip($dst.chunks_mut(SIZE)) {
let tmp = n.to_le();
let src_ptr = &tmp as *const $ty as *const u8;
unsafe {
core::ptr::copy_nonoverlapping(
src_ptr,
chunk.as_mut_ptr(),
chunk.len());
}
}
// Contract: observing self is memory-safe (implies no uninitialised padding)
fn as_byte_slice(x: &[Self]) -> &[u8];
}
impl Observable for u32 {
type Bytes = [u8; 4];
fn to_le_bytes(self) -> Self::Bytes {
self.to_le_bytes()
}
fn as_byte_slice(x: &[Self]) -> &[u8] {
let ptr = x.as_ptr() as *const u8;
let len = x.len() * core::mem::size_of::<Self>();
unsafe { core::slice::from_raw_parts(ptr, len) }
}
}
impl Observable for u64 {
type Bytes = [u8; 8];
fn to_le_bytes(self) -> Self::Bytes {
self.to_le_bytes()
}
fn as_byte_slice(x: &[Self]) -> &[u8] {
let ptr = x.as_ptr() as *const u8;
let len = x.len() * core::mem::size_of::<Self>();
unsafe { core::slice::from_raw_parts(ptr, len) }
}
}
fn fill_via_chunks<T: Observable>(src: &[T], dest: &mut [u8]) -> (usize, usize) {
let size = core::mem::size_of::<T>();
let byte_len = min(src.len() * size, dest.len());
let num_chunks = (byte_len + size - 1) / size;
if cfg!(target_endian = "little") {
// On LE we can do a simple copy, which is 25-50% faster:
dest[..byte_len].copy_from_slice(&T::as_byte_slice(&src[..num_chunks])[..byte_len]);
} else {
// This code is valid on all arches, but slower than the above:
let mut i = 0;
let mut iter = dest[..byte_len].chunks_exact_mut(size);
for chunk in &mut iter {
chunk.copy_from_slice(src[i].to_le_bytes().as_ref());
i += 1;
}
let chunk = iter.into_remainder();
if !chunk.is_empty() {
chunk.copy_from_slice(&src[i].to_le_bytes().as_ref()[..chunk.len()]);
}
}
(chunk_size, chunk_size_u8)
}};
(num_chunks, byte_len)
}
/// Implement `fill_bytes` by reading chunks from the output buffer of a block
@ -115,7 +138,7 @@ macro_rules! fill_via_chunks {
/// }
/// ```
pub fn fill_via_u32_chunks(src: &[u32], dest: &mut [u8]) -> (usize, usize) {
fill_via_chunks!(src, dest, u32)
fill_via_chunks(src, dest)
}
/// Implement `fill_bytes` by reading chunks from the output buffer of a block
@ -129,7 +152,7 @@ pub fn fill_via_u32_chunks(src: &[u32], dest: &mut [u8]) -> (usize, usize) {
///
/// See `fill_via_u32_chunks` for an example.
pub fn fill_via_u64_chunks(src: &[u64], dest: &mut [u8]) -> (usize, usize) {
fill_via_chunks!(src, dest, u64)
fill_via_chunks(src, dest)
}
/// Implement `next_u32` via `fill_bytes`, little-endian order.

37
third_party/rust/rand_core/src/lib.rs поставляемый
Просмотреть файл

@ -196,7 +196,7 @@ pub trait RngCore {
/// Some generators may satisfy an additional property, however this is not
/// required by this trait: if the CSPRNG's state is revealed, it should not be
/// computationally-feasible to reconstruct output prior to this. Some other
/// generators allow backwards-computation and are consided *reversible*.
/// generators allow backwards-computation and are considered *reversible*.
///
/// Note that this trait is provided for guidance only and cannot guarantee
/// suitability for cryptographic applications. In general it should only be
@ -208,6 +208,35 @@ pub trait RngCore {
/// [`BlockRngCore`]: block::BlockRngCore
pub trait CryptoRng {}
/// An extension trait that is automatically implemented for any type
/// implementing [`RngCore`] and [`CryptoRng`].
///
/// It may be used as a trait object, and supports upcasting to [`RngCore`] via
/// the [`CryptoRngCore::as_rngcore`] method.
///
/// # Example
///
/// ```
/// use rand_core::CryptoRngCore;
///
/// #[allow(unused)]
/// fn make_token(rng: &mut dyn CryptoRngCore) -> [u8; 32] {
/// let mut buf = [0u8; 32];
/// rng.fill_bytes(&mut buf);
/// buf
/// }
/// ```
pub trait CryptoRngCore: CryptoRng + RngCore {
/// Upcast to an [`RngCore`] trait object.
fn as_rngcore(&mut self) -> &mut dyn RngCore;
}
impl<T: CryptoRng + RngCore> CryptoRngCore for T {
fn as_rngcore(&mut self) -> &mut dyn RngCore {
self
}
}
/// A random number generator that can be explicitly seeded.
///
/// This trait encapsulates the low-level functionality common to all
@ -215,7 +244,7 @@ pub trait CryptoRng {}
///
/// [`rand`]: https://docs.rs/rand
pub trait SeedableRng: Sized {
/// Seed type, which is restricted to types mutably-dereferencable as `u8`
/// Seed type, which is restricted to types mutably-dereferenceable as `u8`
/// arrays (we recommend `[u8; N]` for some `N`).
///
/// It is recommended to seed PRNGs with a seed of at least circa 100 bits,
@ -448,10 +477,10 @@ impl std::io::Read for dyn RngCore {
}
}
// Implement `CryptoRng` for references to an `CryptoRng`.
// Implement `CryptoRng` for references to a `CryptoRng`.
impl<'a, R: CryptoRng + ?Sized> CryptoRng for &'a mut R {}
// Implement `CryptoRng` for boxed references to an `CryptoRng`.
// Implement `CryptoRng` for boxed references to a `CryptoRng`.
#[cfg(feature = "alloc")]
impl<R: CryptoRng + ?Sized> CryptoRng for Box<R> {}