summaryrefslogtreecommitdiffstats
path: root/vendor/zeroize
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
commit10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch)
treebdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/zeroize
parentReleasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff)
downloadrustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.tar.xz
rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.zip
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/zeroize')
-rw-r--r--vendor/zeroize/.cargo-checksum.json1
-rw-r--r--vendor/zeroize/CHANGELOG.md213
-rw-r--r--vendor/zeroize/Cargo.toml62
-rw-r--r--vendor/zeroize/LICENSE-APACHE202
-rw-r--r--vendor/zeroize/LICENSE-MIT21
-rw-r--r--vendor/zeroize/README.md80
-rw-r--r--vendor/zeroize/src/aarch64.rs35
-rw-r--r--vendor/zeroize/src/lib.rs811
-rw-r--r--vendor/zeroize/src/x86.rs40
-rw-r--r--vendor/zeroize/tests/zeroize.rs210
-rw-r--r--vendor/zeroize/tests/zeroize_derive.rs317
11 files changed, 1992 insertions, 0 deletions
diff --git a/vendor/zeroize/.cargo-checksum.json b/vendor/zeroize/.cargo-checksum.json
new file mode 100644
index 000000000..3e073a166
--- /dev/null
+++ b/vendor/zeroize/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"be6785a1a0ddc3e780c1ea37f1d084ce181a5c8d5dec99968d6400d4d37858f1","Cargo.toml":"fec271d3ae8cdebe28b306043383d60bba0fe9d24a79cece859102c03761c8e7","LICENSE-APACHE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","LICENSE-MIT":"0b04ee3ce0021a922f43f37a17fee09a5a1ee6d1f4e149d5bf75b72395a49c72","README.md":"a1301f2cb985dec479daeecba527cd7fcf1ae6b014e30f818a6c86ef35fd1171","src/aarch64.rs":"5e96f06cc94eee308b8a482e647a5047384324f2230f66095bff88eb4cf55bf0","src/lib.rs":"d02094cdcbcecaa2573ca6460932187e483f5632426e78c680f70182cc01686b","src/x86.rs":"a6e42d07dfba710e6f44010b952e42c3f1f115ec990a35dc6104a004be1eb301","tests/zeroize.rs":"afb60596bbe60130fa18f79a6e8407e2dab71eecf6382593dd114f2111918f9d","tests/zeroize_derive.rs":"0491e4e086415da6ddf4978b38f7a41b65d2f46535378d093db03430f4d0fffc"},"package":"c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f"} \ No newline at end of file
diff --git a/vendor/zeroize/CHANGELOG.md b/vendor/zeroize/CHANGELOG.md
new file mode 100644
index 000000000..83f895874
--- /dev/null
+++ b/vendor/zeroize/CHANGELOG.md
@@ -0,0 +1,213 @@
+# Changelog
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## 1.5.7 (2022-07-20)
+### Added
+- Optional `serde` support ([#780])
+
+[#780]: https://github.com/RustCrypto/utils/pull/780
+
+## 1.5.6 (2022-06-29)
+### Added
+- `#[inline(always)]` annotations ([#772])
+- `#[ignore]` attribute on flaky CString test ([#776])
+
+### Changed
+- Factor integration tests into `tests/` ([#771])
+
+[#771]: https://github.com/RustCrypto/utils/pull/771
+[#772]: https://github.com/RustCrypto/utils/pull/772
+[#776]: https://github.com/RustCrypto/utils/pull/776
+
+## 1.5.5 (2022-04-30)
+### Added
+- Impl `Zeroize` for std::ffi::CString ([#759])
+- `AsRef<T>` and `AsMut<T>` impls for `Zeroizing` ([#761])
+
+[#759]: https://github.com/RustCrypto/utils/pull/759
+[#761]: https://github.com/RustCrypto/utils/pull/761
+
+## 1.5.4 (2022-03-16)
+### Added
+- Nightly-only upport for zeroizing ARM64 SIMD registers ([#749])
+
+[#749]: https://github.com/RustCrypto/utils/pull/749
+
+## 1.5.3 (2022-02-25)
+### Fixed
+- Deriving `ZeroizeOnDrop` on `DerefMut` ([#739])
+
+[#739]: https://github.com/RustCrypto/utils/pull/739
+
+## 1.5.2 (2022-01-31) [YANKED]
+### Fixed
+- Ambiguous method for `AssertZeroizeOnDrop` ([#725])
+
+[#725]: https://github.com/RustCrypto/utils/pull/725
+
+## 1.5.1 (2022-01-27) [YANKED]
+### Fixed
+- Double `mut` on `AssertZeroizeOnDrop` ([#719])
+
+[#719]: https://github.com/RustCrypto/utils/pull/719
+
+## 1.5.0 (2022-01-14) [YANKED]
+### Added
+- `Zeroize` impls for `PhantomData`, `PhantomPinned`, and tuples with 0-10 elements ([#660])
+- `#[zeroize(bound = "T: MyTrait")]` ([#663])
+- `ZeroizeOnDrop` trait and custom derive ([#699], [#700], [#703])
+
+[#660]: https://github.com/RustCrypto/utils/pull/660
+[#663]: https://github.com/RustCrypto/utils/pull/663
+[#699]: https://github.com/RustCrypto/utils/pull/699
+[#700]: https://github.com/RustCrypto/utils/pull/700
+[#703]: https://github.com/RustCrypto/utils/pull/703
+
+## 1.4.3 (2021-11-04)
+### Added
+- Implement `Zeroize` for `NonZeroX`
+
+### Changed
+- Moved to `RustCrypto/utils` repository
+
+## 1.4.2 (2021-09-21)
+### Added
+- Derive `Default` on `Zeroizing`
+
+## 1.4.1 (2021-07-20)
+### Added
+- Implement Zeroize for `[MaybeUninit<Z>]`
+
+## 1.4.0 (2021-07-18)
+NOTE: This release includes an MSRV bump to Rust 1.51. Please use `zeroize = "1.3.0"`
+if you would like to support older Rust versions.
+
+### Added
+- Use const generics to impl `Zeroize` for `[Z; N]`; MSRV 1.51
+- `Zeroizing::clone_from` now zeroizes the destination before cloning
+
+## 1.3.0 (2021-04-19)
+### Added
+- impl `Zeroize` for `Box<[Z]>`
+- Clear residual space within `Option
+
+### Changed
+- Ensure `Option` is `None` when zeroized
+- Bump MSRV to 1.47
+
+## 1.2.0 (2020-12-09)
+### Added
+- `Zeroize` support for x86(_64) SIMD registers
+
+### Changed
+- Simplify `String::zeroize`
+- MSRV 1.44+
+
+## 1.1.1 (2020-09-15)
+- Add `doc_cfg`
+- zeroize entire capacity of `String`
+- zeroize entire capacity of `Vec`
+
+## 1.1.0 (2019-12-02)
+- Add `TryZeroize` trait
+- Add `From<Z: Zeroize>` impl for `Zeroizing<Z>`
+- Remove `bytes-preview` feature
+
+## 1.0.0 (2019-10-13)
+- Initial 1.0 release 🎉
+- zeroize_derive: Remove legacy `no_drop` attribute support
+- Rename `bytes` feature to `bytes-preview`
+- Further relax `Zeroize` trait bounds for `Vec`
+- Derive `Clone`, `Debug`, and `Eq` for `Zeroizing`
+
+## 1.0.0-pre (2019-09-30)
+- Loosen `Vec` trait bounds for `Zeroize`
+
+## 0.10.1 (2019-09-03)
+- (Optionally) Impl `Zeroize` for `Bytes` and `BytesMut`
+
+## 0.10.0 (2019-08-19)
+Barring unforeseen circumstances, this release aims to be the last `0.x`
+release prior to a `zeroize` 1.0 release.
+
+- Disable `zeroize_derive` Cargo feature by default
+- Remove `std` feature in favor of `alloc`; MSRV 1.36+
+- Deprecate `#[zeroize(no_drop)]` attribute
+- Use 1.0 `proc-macro2`, `quote`, and `syn` crates
+
+## 0.9.3 (2019-07-27)
+- Improved attribute parser; fixes nightly build
+
+## 0.9.2 (2019-06-28)
+- README.md: add Gitter badges; update image links
+
+## 0.9.1 (2019-06-04)
+- Impl `Zeroize` for `Option<Z: Zeroize>`
+
+## 0.9.0 (2019-06-04)
+**NOTICE**: This release changes the default behavior of `derive(Zeroize)`
+to no longer derive a `Drop` impl. If you wish to derive `Drop`, you must
+now explicitly add a `#[zeroize(drop)]` attribute on the type for which you
+are deriving `Zeroize`.
+
+- Remove CPU fences
+- Remove scary language about undefined behavior
+- Bound blanket array impls on `Zeroize` instead of `DefaultIsZeroes`
+- Require `zeroize(drop)` or `zeroize(no_drop)` attributes when deriving
+ `Zeroize` .
+- Support stablized 'alloc' crate
+
+## 0.8.0 (2019-05-20)
+- Impl `Drop` by default when deriving `Zeroize`
+
+## 0.7.0 (2019-05-19)
+- Use synstructure for custom derive
+- Add explicit array impls for `DefaultIsZeroes`
+- Remove `nightly` feature
+- Add `Zeroizing<Z>` to zeroize values on drop
+
+## 0.6.0 (2019-03-23)
+- Add ZeroizeOnDrop marker trait + custom derive
+- Custom derive support for `Zeroize`
+- Rename `ZeroizeWithDefault` to `DefaultIsZeroes`
+
+## 0.5.2 (2018-12-25)
+- Add `debug_assert!` to ensure string interiors are zeroized
+
+## 0.5.1 (2018-12-24)
+- Avoid re-exporting the whole prelude
+
+## 0.5.0 (2018-12-24)
+This release is a rewrite which replaces FFI bindings to OS-specific APIs with
+a pure Rust solution.
+
+- Use `core::sync::atomic` fences
+- Test wasm target
+- Rewrite using `core::ptr::write_volatile`
+
+## 0.4.2 (2018-10-12)
+- Fix ldd scraper for older glibc versions
+
+## 0.4.1 (2018-10-12)
+- Support musl-libc
+
+## 0.4.0 (2018-10-12)
+- Impl `Zeroize` trait on concrete types
+
+## 0.3.0 (2018-10-11)
+- Replace `secure_zero_memory` with `Zeroize`
+
+## 0.2.0 (2018-10-11)
+- Add `Zeroize` trait
+
+## 0.1.2 (2018-10-03)
+- README.md: Fix intrinsic links
+
+## 0.1.1 (2018-10-03)
+- Documentation improvements
+
+## 0.1.0 (2018-10-03)
+- Initial release
diff --git a/vendor/zeroize/Cargo.toml b/vendor/zeroize/Cargo.toml
new file mode 100644
index 000000000..a70f55180
--- /dev/null
+++ b/vendor/zeroize/Cargo.toml
@@ -0,0 +1,62 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# 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.
+#
+# 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 = "zeroize"
+version = "1.5.7"
+authors = ["The RustCrypto Project Developers"]
+description = """
+Securely clear secrets from memory with a simple trait built on
+stable Rust primitives which guarantee memory is zeroed using an
+operation will not be 'optimized away' by the compiler.
+Uses a portable pure Rust implementation that works everywhere,
+even WASM!
+"""
+readme = "README.md"
+keywords = [
+ "memory",
+ "memset",
+ "secure",
+ "volatile",
+ "zero",
+]
+categories = [
+ "cryptography",
+ "memory-management",
+ "no-std",
+ "os",
+]
+license = "Apache-2.0 OR MIT"
+repository = "https://github.com/RustCrypto/utils/tree/master/zeroize"
+
+[package.metadata.docs.rs]
+all-features = true
+rustdoc-args = [
+ "--cfg",
+ "docsrs",
+]
+
+[dependencies.serde]
+version = "1.0"
+optional = true
+default-features = false
+
+[dependencies.zeroize_derive]
+version = "1.3"
+optional = true
+
+[features]
+aarch64 = []
+alloc = []
+default = ["alloc"]
+derive = ["zeroize_derive"]
+std = ["alloc"]
diff --git a/vendor/zeroize/LICENSE-APACHE b/vendor/zeroize/LICENSE-APACHE
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/vendor/zeroize/LICENSE-APACHE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ 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
+
+ http://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.
diff --git a/vendor/zeroize/LICENSE-MIT b/vendor/zeroize/LICENSE-MIT
new file mode 100644
index 000000000..3a2b00413
--- /dev/null
+++ b/vendor/zeroize/LICENSE-MIT
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018-2021 The RustCrypto Project Developers
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/zeroize/README.md b/vendor/zeroize/README.md
new file mode 100644
index 000000000..4f71ab432
--- /dev/null
+++ b/vendor/zeroize/README.md
@@ -0,0 +1,80 @@
+# [RustCrypto]: zeroize
+
+[![Crate][crate-image]][crate-link]
+[![Docs][docs-image]][docs-link]
+![Apache 2.0/MIT Licensed][license-image]
+![MSRV][rustc-image]
+[![Build Status][build-image]][build-link]
+
+Securely zero memory (a.k.a. [zeroize]) while avoiding compiler optimizations.
+
+This crate implements a portable approach to securely zeroing memory using
+techniques which guarantee they won't be "optimized away" by the compiler.
+
+The [`Zeroize` trait] is the crate's primary API.
+
+[Documentation]
+
+## About
+
+[Zeroing memory securely is hard] - compilers optimize for performance, and
+in doing so they love to "optimize away" unnecessary zeroing calls. There are
+many documented "tricks" to attempt to avoid these optimizations and ensure
+that a zeroing routine is performed reliably.
+
+This crate isn't about tricks: it uses [core::ptr::write_volatile]
+and [core::sync::atomic] memory fences to provide easy-to-use, portable
+zeroing behavior which works on all of Rust's core number types and slices
+thereof, implemented in pure Rust with no usage of FFI or assembly.
+
+- No insecure fallbacks!
+- No dependencies!
+- No FFI or inline assembly! **WASM friendly** (and tested)!
+- `#![no_std]` i.e. **embedded-friendly**!
+- No functionality besides securely zeroing memory!
+- (Optional) Custom derive support for zeroing complex structures
+
+## Minimum Supported Rust Version
+
+Rust **1.51** or newer.
+
+In the future, we reserve the right to change MSRV (i.e. MSRV is out-of-scope
+for this crate's SemVer guarantees), however when we do it will be accompanied by
+a minor version bump.
+
+## License
+
+Licensed under either of:
+
+* [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+* [MIT license](http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
+
+[//]: # (badges)
+
+[crate-image]: https://img.shields.io/crates/v/zeroize.svg
+[crate-link]: https://crates.io/crates/zeroize
+[docs-image]: https://docs.rs/zeroize/badge.svg
+[docs-link]: https://docs.rs/zeroize/
+[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
+[rustc-image]: https://img.shields.io/badge/rustc-1.51+-blue.svg
+[build-image]: https://github.com/RustCrypto/utils/actions/workflows/zeroize.yml/badge.svg
+[build-link]: https://github.com/RustCrypto/utils/actions/workflows/zeroize.yml
+
+[//]: # (general links)
+
+[RustCrypto]: https://github.com/RustCrypto
+[zeroize]: https://en.wikipedia.org/wiki/Zeroisation
+[`Zeroize` trait]: https://docs.rs/zeroize/latest/zeroize/trait.Zeroize.html
+[Documentation]: https://docs.rs/zeroize/
+[Zeroing memory securely is hard]: http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
+[core::ptr::write_volatile]: https://doc.rust-lang.org/core/ptr/fn.write_volatile.html
+[core::sync::atomic]: https://doc.rust-lang.org/stable/core/sync/atomic/index.html
+[good cryptographic hygiene]: https://github.com/veorq/cryptocoding#clean-memory-of-secret-data
diff --git a/vendor/zeroize/src/aarch64.rs b/vendor/zeroize/src/aarch64.rs
new file mode 100644
index 000000000..fc6c8f23d
--- /dev/null
+++ b/vendor/zeroize/src/aarch64.rs
@@ -0,0 +1,35 @@
+//! [`Zeroize`] impls for ARM64 SIMD registers.
+//!
+//! Support for this is gated behind an `aarch64` feature because
+//! support for `core::arch::aarch64` is currently nightly-only.
+
+use crate::{atomic_fence, volatile_write, Zeroize};
+
+use core::arch::aarch64::*;
+
+macro_rules! impl_zeroize_for_simd_register {
+ ($(($type:ty, $vdupq:ident)),+) => {
+ $(
+ #[cfg_attr(docsrs, doc(cfg(target_arch = "aarch64")))]
+ #[cfg_attr(docsrs, doc(cfg(target_feature = "neon")))]
+ impl Zeroize for $type {
+ fn zeroize(&mut self) {
+ volatile_write(self, unsafe { $vdupq(0) });
+ atomic_fence();
+ }
+ }
+ )+
+ };
+}
+
+// TODO(tarcieri): other NEON register types?
+impl_zeroize_for_simd_register! {
+ (uint8x8_t, vdup_n_u8),
+ (uint8x16_t, vdupq_n_u8),
+ (uint16x4_t, vdup_n_u16),
+ (uint16x8_t, vdupq_n_u16),
+ (uint32x2_t, vdup_n_u32),
+ (uint32x4_t, vdupq_n_u32),
+ (uint64x1_t, vdup_n_u64),
+ (uint64x2_t, vdupq_n_u64)
+}
diff --git a/vendor/zeroize/src/lib.rs b/vendor/zeroize/src/lib.rs
new file mode 100644
index 000000000..5ee0f2c96
--- /dev/null
+++ b/vendor/zeroize/src/lib.rs
@@ -0,0 +1,811 @@
+#![no_std]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+#![doc(
+ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
+ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
+)]
+#![warn(missing_docs, rust_2018_idioms, unused_qualifications)]
+
+//! Securely zero memory with a simple trait ([`Zeroize`]) built on stable Rust
+//! primitives which guarantee the operation will not be "optimized away".
+//!
+//! ## About
+//!
+//! [Zeroing memory securely is hard] - compilers optimize for performance, and
+//! in doing so they love to "optimize away" unnecessary zeroing calls. There are
+//! many documented "tricks" to attempt to avoid these optimizations and ensure
+//! that a zeroing routine is performed reliably.
+//!
+//! This crate isn't about tricks: it uses [`core::ptr::write_volatile`]
+//! and [`core::sync::atomic`] memory fences to provide easy-to-use, portable
+//! zeroing behavior which works on all of Rust's core number types and slices
+//! thereof, implemented in pure Rust with no usage of FFI or assembly.
+//!
+//! - No insecure fallbacks!
+//! - No dependencies!
+//! - No FFI or inline assembly! **WASM friendly** (and tested)!
+//! - `#![no_std]` i.e. **embedded-friendly**!
+//! - No functionality besides securely zeroing memory!
+//! - (Optional) Custom derive support for zeroing complex structures
+//!
+//! ## Minimum Supported Rust Version
+//!
+//! Requires Rust **1.51** or newer.
+//!
+//! In the future, we reserve the right to change MSRV (i.e. MSRV is out-of-scope
+//! for this crate's SemVer guarantees), however when we do it will be accompanied
+//! by a minor version bump.
+//!
+//! ## Usage
+//!
+//! ```
+//! use zeroize::Zeroize;
+//!
+//! fn main() {
+//! // Protip: don't embed secrets in your source code.
+//! // This is just an example.
+//! let mut secret = b"Air shield password: 1,2,3,4,5".to_vec();
+//! // [ ... ] open the air shield here
+//!
+//! // Now that we're done using the secret, zero it out.
+//! secret.zeroize();
+//! }
+//! ```
+//!
+//! The [`Zeroize`] trait is impl'd on all of Rust's core scalar types including
+//! integers, floats, `bool`, and `char`.
+//!
+//! Additionally, it's implemented on slices and `IterMut`s of the above types.
+//!
+//! When the `alloc` feature is enabled (which it is by default), it's also
+//! impl'd for `Vec<T>` for the above types as well as `String`, where it provides
+//! [`Vec::clear`] / [`String::clear`]-like behavior (truncating to zero-length)
+//! but ensures the backing memory is securely zeroed with some caveats.
+//!
+//! With the `std` feature enabled (which it is **not** by default), [`Zeroize`]
+//! is also implemented for [`CString`]. After calling `zeroize()` on a `CString`,
+//! it will its internal buffer will contain exactly one nul byte. The backing
+//! memory is zeroed by converting it to a `Vec<u8>` and back into a `CString`.
+//! (NOTE: see "Stack/Heap Zeroing Notes" for important `Vec`/`String`/`CString` details)
+//!
+//!
+//! The [`DefaultIsZeroes`] marker trait can be impl'd on types which also
+//! impl [`Default`], which implements [`Zeroize`] by overwriting a value with
+//! the default value.
+//!
+//! ## Custom Derive Support
+//!
+//! This crate has custom derive support for the `Zeroize` trait,
+//! gated under the `zeroize` crate's `zeroize_derive` Cargo feature,
+//! which automatically calls `zeroize()` on all members of a struct
+//! or tuple struct.
+//!
+//! Attributes supported for `Zeroize`:
+//!
+//! On the item level:
+//! - `#[zeroize(drop)]`: *deprecated* use `ZeroizeOnDrop` instead
+//! - `#[zeroize(bound = "T: MyTrait")]`: this replaces any trait bounds
+//! inferred by zeroize
+//!
+//! On the field level:
+//! - `#[zeroize(skip)]`: skips this field or variant when calling `zeroize()`
+//!
+//! Attributes supported for `ZeroizeOnDrop`:
+//!
+//! On the field level:
+//! - `#[zeroize(skip)]`: skips this field or variant when calling `zeroize()`
+//!
+//! Example which derives `Drop`:
+//!
+//! ```
+//! # #[cfg(feature = "zeroize_derive")]
+//! # {
+//! use zeroize::{Zeroize, ZeroizeOnDrop};
+//!
+//! // This struct will be zeroized on drop
+//! #[derive(Zeroize, ZeroizeOnDrop)]
+//! struct MyStruct([u8; 32]);
+//! # }
+//! ```
+//!
+//! Example which does not derive `Drop` (useful for e.g. `Copy` types)
+//!
+//! ```
+//! #[cfg(feature = "zeroize_derive")]
+//! # {
+//! use zeroize::Zeroize;
+//!
+//! // This struct will *NOT* be zeroized on drop
+//! #[derive(Copy, Clone, Zeroize)]
+//! struct MyStruct([u8; 32]);
+//! # }
+//! ```
+//!
+//! Example which only derives `Drop`:
+//!
+//! ```
+//! # #[cfg(feature = "zeroize_derive")]
+//! # {
+//! use zeroize::ZeroizeOnDrop;
+//!
+//! // This struct will be zeroized on drop
+//! #[derive(ZeroizeOnDrop)]
+//! struct MyStruct([u8; 32]);
+//! # }
+//! ```
+//!
+//! ## `Zeroizing<Z>`: wrapper for zeroizing arbitrary values on drop
+//!
+//! `Zeroizing<Z: Zeroize>` is a generic wrapper type that impls `Deref`
+//! and `DerefMut`, allowing access to an inner value of type `Z`, and also
+//! impls a `Drop` handler which calls `zeroize()` on its contents:
+//!
+//! ```
+//! use zeroize::Zeroizing;
+//!
+//! fn main() {
+//! let mut secret = Zeroizing::new([0u8; 5]);
+//!
+//! // Set the air shield password
+//! // Protip (again): don't embed secrets in your source code.
+//! secret.copy_from_slice(&[1, 2, 3, 4, 5]);
+//! assert_eq!(secret.as_ref(), &[1, 2, 3, 4, 5]);
+//!
+//! // The contents of `secret` will be automatically zeroized on drop
+//! }
+//! ```
+//!
+//! ## What guarantees does this crate provide?
+//!
+//! This crate guarantees the following:
+//!
+//! 1. The zeroing operation can't be "optimized away" by the compiler.
+//! 2. All subsequent reads to memory will see "zeroized" values.
+//!
+//! LLVM's volatile semantics ensure #1 is true.
+//!
+//! Additionally, thanks to work by the [Unsafe Code Guidelines Working Group],
+//! we can now fairly confidently say #2 is true as well. Previously there were
+//! worries that the approach used by this crate (mixing volatile and
+//! non-volatile accesses) was undefined behavior due to language contained
+//! in the documentation for `write_volatile`, however after some discussion
+//! [these remarks have been removed] and the specific usage pattern in this
+//! crate is considered to be well-defined.
+//!
+//! Additionally this crate leverages [`core::sync::atomic::compiler_fence`]
+//! with the strictest ordering
+//! ([`Ordering::SeqCst`]) as a
+//! precaution to help ensure reads are not reordered before memory has been
+//! zeroed.
+//!
+//! All of that said, there is still potential for microarchitectural attacks
+//! (ala Spectre/Meltdown) to leak "zeroized" secrets through covert channels.
+//! This crate makes no guarantees that zeroized values cannot be leaked
+//! through such channels, as they represent flaws in the underlying hardware.
+//!
+//! ## Stack/Heap Zeroing Notes
+//!
+//! This crate can be used to zero values from either the stack or the heap.
+//!
+//! However, be aware several operations in Rust can unintentionally leave
+//! copies of data in memory. This includes but is not limited to:
+//!
+//! - Moves and [`Copy`]
+//! - Heap reallocation when using [`Vec`] and [`String`]
+//! - Borrowers of a reference making copies of the data
+//!
+//! [`Pin`][`core::pin::Pin`] can be leveraged in conjunction with this crate
+//! to ensure data kept on the stack isn't moved.
+//!
+//! The `Zeroize` impls for `Vec`, `String` and `CString` zeroize the entire
+//! capacity of their backing buffer, but cannot guarantee copies of the data
+//! were not previously made by buffer reallocation. It's therefore important
+//! when attempting to zeroize such buffers to initialize them to the correct
+//! capacity, and take care to prevent subsequent reallocation.
+//!
+//! The `secrecy` crate provides higher-level abstractions for eliminating
+//! usage patterns which can cause reallocations:
+//!
+//! <https://crates.io/crates/secrecy>
+//!
+//! ## What about: clearing registers, mlock, mprotect, etc?
+//!
+//! This crate is focused on providing simple, unobtrusive support for reliably
+//! zeroing memory using the best approach possible on stable Rust.
+//!
+//! Clearing registers is a difficult problem that can't easily be solved by
+//! something like a crate, and requires either inline ASM or rustc support.
+//! See <https://github.com/rust-lang/rust/issues/17046> for background on
+//! this particular problem.
+//!
+//! Other memory protection mechanisms are interesting and useful, but often
+//! overkill (e.g. defending against RAM scraping or attackers with swap access).
+//! In as much as there may be merit to these approaches, there are also many
+//! other crates that already implement more sophisticated memory protections.
+//! Such protections are explicitly out-of-scope for this crate.
+//!
+//! Zeroing memory is [good cryptographic hygiene] and this crate seeks to promote
+//! it in the most unobtrusive manner possible. This includes omitting complex
+//! `unsafe` memory protection systems and just trying to make the best memory
+//! zeroing crate available.
+//!
+//! [Zeroing memory securely is hard]: http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
+//! [Unsafe Code Guidelines Working Group]: https://github.com/rust-lang/unsafe-code-guidelines
+//! [these remarks have been removed]: https://github.com/rust-lang/rust/pull/60972
+//! [good cryptographic hygiene]: https://github.com/veorq/cryptocoding#clean-memory-of-secret-data
+//! [`Ordering::SeqCst`]: core::sync::atomic::Ordering::SeqCst
+
+#[cfg(feature = "alloc")]
+extern crate alloc;
+
+#[cfg(feature = "std")]
+extern crate std;
+
+#[cfg(feature = "zeroize_derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "zeroize_derive")))]
+pub use zeroize_derive::{Zeroize, ZeroizeOnDrop};
+
+#[cfg(all(feature = "aarch64", target_arch = "aarch64"))]
+mod aarch64;
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+mod x86;
+
+use core::{
+ marker::{PhantomData, PhantomPinned},
+ mem::{self, MaybeUninit},
+ num::{
+ NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
+ NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
+ },
+ ops, ptr,
+ slice::IterMut,
+ sync::atomic,
+};
+
+#[cfg(feature = "alloc")]
+use {
+ alloc::{boxed::Box, string::String, vec::Vec},
+ core::slice,
+};
+
+#[cfg(feature = "std")]
+use std::ffi::CString;
+
+/// Trait for securely erasing values from memory.
+pub trait Zeroize {
+ /// Zero out this object from memory using Rust intrinsics which ensure the
+ /// zeroization operation is not "optimized away" by the compiler.
+ fn zeroize(&mut self);
+}
+
+/// Marker trait signifying that this type will [`Zeroize::zeroize`] itself on [`Drop`].
+pub trait ZeroizeOnDrop {}
+
+/// Marker trait for types whose [`Default`] is the desired zeroization result
+pub trait DefaultIsZeroes: Copy + Default + Sized {}
+
+/// Fallible trait for representing cases where zeroization may or may not be
+/// possible.
+///
+/// This is primarily useful for scenarios like reference counted data, where
+/// zeroization is only possible when the last reference is dropped.
+pub trait TryZeroize {
+ /// Try to zero out this object from memory using Rust intrinsics which
+ /// ensure the zeroization operation is not "optimized away" by the
+ /// compiler.
+ #[must_use]
+ fn try_zeroize(&mut self) -> bool;
+}
+
+impl<Z> Zeroize for Z
+where
+ Z: DefaultIsZeroes,
+{
+ fn zeroize(&mut self) {
+ volatile_write(self, Z::default());
+ atomic_fence();
+ }
+}
+
+macro_rules! impl_zeroize_with_default {
+ ($($type:ty),+) => {
+ $(impl DefaultIsZeroes for $type {})+
+ };
+}
+
+#[rustfmt::skip]
+impl_zeroize_with_default! {
+ bool, char,
+ f32, f64,
+ i8, i16, i32, i64, i128, isize,
+ u8, u16, u32, u64, u128, usize
+}
+
+macro_rules! impl_zeroize_for_non_zero {
+ ($($type:ty),+) => {
+ $(
+ impl Zeroize for $type {
+ fn zeroize(&mut self) {
+ volatile_write(self, unsafe { <$type>::new_unchecked(1) });
+ atomic_fence();
+ }
+ }
+ )+
+ };
+}
+
+impl_zeroize_for_non_zero!(
+ NonZeroI8,
+ NonZeroI16,
+ NonZeroI32,
+ NonZeroI64,
+ NonZeroI128,
+ NonZeroIsize,
+ NonZeroU8,
+ NonZeroU16,
+ NonZeroU32,
+ NonZeroU64,
+ NonZeroU128,
+ NonZeroUsize
+);
+
+/// Impl [`Zeroize`] on arrays of types that impl [`Zeroize`].
+impl<Z, const N: usize> Zeroize for [Z; N]
+where
+ Z: Zeroize,
+{
+ fn zeroize(&mut self) {
+ self.iter_mut().zeroize();
+ }
+}
+
+/// Impl [`ZeroizeOnDrop`] on arrays of types that impl [`ZeroizeOnDrop`].
+impl<Z, const N: usize> ZeroizeOnDrop for [Z; N] where Z: ZeroizeOnDrop {}
+
+impl<'a, Z> Zeroize for IterMut<'a, Z>
+where
+ Z: Zeroize,
+{
+ fn zeroize(&mut self) {
+ for elem in self {
+ elem.zeroize();
+ }
+ }
+}
+
+impl<Z> Zeroize for Option<Z>
+where
+ Z: Zeroize,
+{
+ fn zeroize(&mut self) {
+ if let Some(value) = self {
+ value.zeroize();
+
+ // Ensures self is None and that the value was dropped. Without the take, the drop
+ // of the (zeroized) value isn't called, which might lead to a leak or other
+ // unexpected behavior. For example, if this were Option<Vec<T>>, the above call to
+ // zeroize would not free the allocated memory, but the the `take` call will.
+ self.take();
+ }
+
+ // Ensure that if the `Option` were previously `Some` but a value was copied/moved out
+ // that the remaining space in the `Option` is zeroized.
+ //
+ // Safety:
+ //
+ // The memory pointed to by `self` is valid for `mem::size_of::<Self>()` bytes.
+ // It is also properly aligned, because `u8` has an alignment of `1`.
+ unsafe {
+ volatile_set(self as *mut _ as *mut u8, 0, mem::size_of::<Self>());
+ }
+
+ // Ensures self is overwritten with the default bit pattern. volatile_write can't be
+ // used because Option<Z> is not copy.
+ //
+ // Safety:
+ //
+ // self is safe to replace with the default, which the take() call above should have
+ // already done semantically. Any value which needed to be dropped will have been
+ // done so by take().
+ unsafe { ptr::write_volatile(self, Option::default()) }
+
+ atomic_fence();
+ }
+}
+
+impl<Z> ZeroizeOnDrop for Option<Z> where Z: ZeroizeOnDrop {}
+
+/// Impl [`Zeroize`] on slices of [`MaybeUninit`] types.
+///
+/// This impl can eventually be optimized using an memset intrinsic,
+/// such as [`core::intrinsics::volatile_set_memory`].
+///
+/// This fills the slice with zeroes.
+///
+/// Note that this ignore invariants that `Z` might have, because
+/// [`MaybeUninit`] removes all invariants.
+impl<Z> Zeroize for [MaybeUninit<Z>] {
+ fn zeroize(&mut self) {
+ let ptr = self.as_mut_ptr() as *mut MaybeUninit<u8>;
+ let size = self.len().checked_mul(mem::size_of::<Z>()).unwrap();
+ assert!(size <= isize::MAX as usize);
+
+ // Safety:
+ //
+ // This is safe, because every valid pointer is well aligned for u8
+ // and it is backed by a single allocated object for at least `self.len() * size_pf::<Z>()` bytes.
+ // and 0 is a valid value for `MaybeUninit<Z>`
+ // The memory of the slice should not wrap around the address space.
+ unsafe { volatile_set(ptr, MaybeUninit::new(0), size) }
+ atomic_fence();
+ }
+}
+
+/// Impl [`Zeroize`] on slices of types that can be zeroized with [`Default`].
+///
+/// This impl can eventually be optimized using an memset intrinsic,
+/// such as [`core::intrinsics::volatile_set_memory`]. For that reason the
+/// blanket impl on slices is bounded by [`DefaultIsZeroes`].
+///
+/// To zeroize a mut slice of `Z: Zeroize` which does not impl
+/// [`DefaultIsZeroes`], call `iter_mut().zeroize()`.
+impl<Z> Zeroize for [Z]
+where
+ Z: DefaultIsZeroes,
+{
+ fn zeroize(&mut self) {
+ assert!(self.len() <= isize::MAX as usize);
+
+ // Safety:
+ //
+ // This is safe, because the slice is well aligned and is backed by a single allocated
+ // object for at least `self.len()` elements of type `Z`.
+ // `self.len()` is also not larger than an `isize`, because of the assertion above.
+ // The memory of the slice should not wrap around the address space.
+ unsafe { volatile_set(self.as_mut_ptr(), Z::default(), self.len()) };
+ atomic_fence();
+ }
+}
+
+/// [`PhantomData`] is always zero sized so provide a [`Zeroize`] implementation.
+impl<Z> Zeroize for PhantomData<Z> {
+ fn zeroize(&mut self) {}
+}
+
+/// [`PhantomData` is always zero sized so provide a ZeroizeOnDrop implementation.
+impl<Z> ZeroizeOnDrop for PhantomData<Z> {}
+
+/// `PhantomPinned` is zero sized so provide a Zeroize implementation.
+impl Zeroize for PhantomPinned {
+ fn zeroize(&mut self) {}
+}
+
+/// `PhantomPinned` is zero sized so provide a ZeroizeOnDrop implementation.
+impl ZeroizeOnDrop for PhantomPinned {}
+
+/// `()` is zero sized so provide a Zeroize implementation.
+impl Zeroize for () {
+ fn zeroize(&mut self) {}
+}
+
+/// `()` is zero sized so provide a ZeroizeOnDrop implementation.
+impl ZeroizeOnDrop for () {}
+
+/// Generic implementation of Zeroize for tuples up to 10 parameters.
+impl<A: Zeroize> Zeroize for (A,) {
+ fn zeroize(&mut self) {
+ self.0.zeroize();
+ }
+}
+
+/// Generic implementation of ZeroizeOnDrop for tuples up to 10 parameters.
+impl<A: ZeroizeOnDrop> ZeroizeOnDrop for (A,) {}
+
+macro_rules! impl_zeroize_tuple {
+ ( $( $type_name:ident ),+ ) => {
+ impl<$($type_name: Zeroize),+> Zeroize for ($($type_name),+) {
+ fn zeroize(&mut self) {
+ #[allow(non_snake_case)]
+ let ($($type_name),+) = self;
+ $($type_name.zeroize());+
+ }
+ }
+
+ impl<$($type_name: ZeroizeOnDrop),+> ZeroizeOnDrop for ($($type_name),+) { }
+ }
+}
+
+// Generic implementations for tuples up to 10 parameters.
+impl_zeroize_tuple!(A, B);
+impl_zeroize_tuple!(A, B, C);
+impl_zeroize_tuple!(A, B, C, D);
+impl_zeroize_tuple!(A, B, C, D, E);
+impl_zeroize_tuple!(A, B, C, D, E, F);
+impl_zeroize_tuple!(A, B, C, D, E, F, G);
+impl_zeroize_tuple!(A, B, C, D, E, F, G, H);
+impl_zeroize_tuple!(A, B, C, D, E, F, G, H, I);
+impl_zeroize_tuple!(A, B, C, D, E, F, G, H, I, J);
+
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+impl<Z> Zeroize for Vec<Z>
+where
+ Z: Zeroize,
+{
+ /// "Best effort" zeroization for `Vec`.
+ ///
+ /// Ensures the entire capacity of the `Vec` is zeroed. Cannot ensure that
+ /// previous reallocations did not leave values on the heap.
+ fn zeroize(&mut self) {
+ // Zeroize all the initialized elements.
+ self.iter_mut().zeroize();
+
+ // Set the Vec's length to 0 and drop all the elements.
+ self.clear();
+
+ // Zero the full capacity of `Vec`.
+ // Safety:
+ //
+ // This is safe, because `Vec` never allocates more than `isize::MAX` bytes.
+ // This exact use case is even mentioned in the documentation of `pointer::add`.
+ // This is safe because MaybeUninit ignores all invariants,
+ // so we can create a slice of MaybeUninit<Z> using the full capacity of the Vec
+ let uninit_slice = unsafe {
+ slice::from_raw_parts_mut(self.as_mut_ptr() as *mut MaybeUninit<Z>, self.capacity())
+ };
+
+ uninit_slice.zeroize();
+ }
+}
+
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+impl<Z> ZeroizeOnDrop for Vec<Z> where Z: ZeroizeOnDrop {}
+
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+impl<Z> Zeroize for Box<[Z]>
+where
+ Z: Zeroize,
+{
+ /// Unlike `Vec`, `Box<[Z]>` cannot reallocate, so we can be sure that we are not leaving
+ /// values on the heap.
+ fn zeroize(&mut self) {
+ self.iter_mut().zeroize();
+ }
+}
+
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+impl<Z> ZeroizeOnDrop for Box<[Z]> where Z: ZeroizeOnDrop {}
+
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+impl Zeroize for String {
+ fn zeroize(&mut self) {
+ unsafe { self.as_mut_vec() }.zeroize();
+ }
+}
+
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+impl Zeroize for CString {
+ fn zeroize(&mut self) {
+ // mem::take uses replace internally to swap the pointer
+ // Unfortunately this results in an allocation for a Box::new(&[0]) as CString must
+ // contain a trailing zero byte
+ let this = mem::take(self);
+
+ // - CString::into_bytes calls ::into_vec which takes ownership of the heap pointer
+ // as a Vec<u8>
+ // - Calling .zeroize() on the resulting vector clears out the bytes
+ // From: https://github.com/RustCrypto/utils/pull/759#issuecomment-1087976570
+ let mut buf = this.into_bytes();
+ buf.zeroize();
+
+ // expect() should never fail, because zeroize() truncates the Vec
+ let zeroed = CString::new(buf).expect("buf not truncated");
+
+ // Replace self by the zeroed CString to maintain the original ptr of the buffer
+ let _ = mem::replace(self, zeroed);
+ }
+}
+
+/// `Zeroizing` is a a wrapper for any `Z: Zeroize` type which implements a
+/// `Drop` handler which zeroizes dropped values.
+#[derive(Debug, Default, Eq, PartialEq)]
+pub struct Zeroizing<Z: Zeroize>(Z);
+
+impl<Z> Zeroizing<Z>
+where
+ Z: Zeroize,
+{
+ /// Move value inside a `Zeroizing` wrapper which ensures it will be
+ /// zeroized when it's dropped.
+ #[inline(always)]
+ pub fn new(value: Z) -> Self {
+ Self(value)
+ }
+}
+
+impl<Z: Zeroize + Clone> Clone for Zeroizing<Z> {
+ #[inline(always)]
+ fn clone(&self) -> Self {
+ Self(self.0.clone())
+ }
+
+ #[inline(always)]
+ fn clone_from(&mut self, source: &Self) {
+ self.0.zeroize();
+ self.0.clone_from(&source.0);
+ }
+}
+
+impl<Z> From<Z> for Zeroizing<Z>
+where
+ Z: Zeroize,
+{
+ #[inline(always)]
+ fn from(value: Z) -> Zeroizing<Z> {
+ Zeroizing(value)
+ }
+}
+
+impl<Z> ops::Deref for Zeroizing<Z>
+where
+ Z: Zeroize,
+{
+ type Target = Z;
+
+ #[inline(always)]
+ fn deref(&self) -> &Z {
+ &self.0
+ }
+}
+
+impl<Z> ops::DerefMut for Zeroizing<Z>
+where
+ Z: Zeroize,
+{
+ #[inline(always)]
+ fn deref_mut(&mut self) -> &mut Z {
+ &mut self.0
+ }
+}
+
+impl<T, Z> AsRef<T> for Zeroizing<Z>
+where
+ T: ?Sized,
+ Z: AsRef<T> + Zeroize,
+{
+ #[inline(always)]
+ fn as_ref(&self) -> &T {
+ self.0.as_ref()
+ }
+}
+
+impl<T, Z> AsMut<T> for Zeroizing<Z>
+where
+ T: ?Sized,
+ Z: AsMut<T> + Zeroize,
+{
+ #[inline(always)]
+ fn as_mut(&mut self) -> &mut T {
+ self.0.as_mut()
+ }
+}
+
+impl<Z> Zeroize for Zeroizing<Z>
+where
+ Z: Zeroize,
+{
+ fn zeroize(&mut self) {
+ self.0.zeroize();
+ }
+}
+
+impl<Z> ZeroizeOnDrop for Zeroizing<Z> where Z: Zeroize {}
+
+impl<Z> Drop for Zeroizing<Z>
+where
+ Z: Zeroize,
+{
+ fn drop(&mut self) {
+ self.0.zeroize()
+ }
+}
+
+#[cfg(feature = "serde")]
+impl<Z> serde::Serialize for Zeroizing<Z>
+where
+ Z: Zeroize + serde::Serialize,
+{
+ #[inline(always)]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: serde::Serializer,
+ {
+ self.0.serialize(serializer)
+ }
+}
+
+#[cfg(feature = "serde")]
+impl<'de, Z> serde::Deserialize<'de> for Zeroizing<Z>
+where
+ Z: Zeroize + serde::Deserialize<'de>,
+{
+ #[inline(always)]
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ Ok(Self(Z::deserialize(deserializer)?))
+ }
+}
+
+/// Use fences to prevent accesses from being reordered before this
+/// point, which should hopefully help ensure that all accessors
+/// see zeroes after this point.
+#[inline(always)]
+fn atomic_fence() {
+ atomic::compiler_fence(atomic::Ordering::SeqCst);
+}
+
+/// Perform a volatile write to the destination
+#[inline(always)]
+fn volatile_write<T: Copy + Sized>(dst: &mut T, src: T) {
+ unsafe { ptr::write_volatile(dst, src) }
+}
+
+/// Perform a volatile `memset` operation which fills a slice with a value
+///
+/// Safety:
+/// The memory pointed to by `dst` must be a single allocated object that is valid for `count`
+/// contiguous elements of `T`.
+/// `count` must not be larger than an `isize`.
+/// `dst` being offset by `mem::size_of::<T> * count` bytes must not wrap around the address space.
+/// Also `dst` must be properly aligned.
+#[inline(always)]
+unsafe fn volatile_set<T: Copy + Sized>(dst: *mut T, src: T, count: usize) {
+ // TODO(tarcieri): use `volatile_set_memory` when stabilized
+ for i in 0..count {
+ // Safety:
+ //
+ // This is safe because there is room for at least `count` objects of type `T` in the
+ // allocation pointed to by `dst`, because `count <= isize::MAX` and because
+ // `dst.add(count)` must not wrap around the address space.
+ let ptr = dst.add(i);
+
+ // Safety:
+ //
+ // This is safe, because the pointer is valid and because `dst` is well aligned for `T` and
+ // `ptr` is an offset of `dst` by a multiple of `mem::size_of::<T>()` bytes.
+ ptr::write_volatile(ptr, src);
+ }
+}
+
+/// Internal module used as support for `AssertZeroizeOnDrop`.
+#[doc(hidden)]
+pub mod __internal {
+ use super::*;
+
+ /// Auto-deref workaround for deriving `ZeroizeOnDrop`.
+ pub trait AssertZeroizeOnDrop {
+ fn zeroize_or_on_drop(self);
+ }
+
+ impl<T: ZeroizeOnDrop + ?Sized> AssertZeroizeOnDrop for &&mut T {
+ fn zeroize_or_on_drop(self) {}
+ }
+
+ /// Auto-deref workaround for deriving `ZeroizeOnDrop`.
+ pub trait AssertZeroize {
+ fn zeroize_or_on_drop(&mut self);
+ }
+
+ impl<T: Zeroize + ?Sized> AssertZeroize for T {
+ fn zeroize_or_on_drop(&mut self) {
+ self.zeroize()
+ }
+ }
+}
diff --git a/vendor/zeroize/src/x86.rs b/vendor/zeroize/src/x86.rs
new file mode 100644
index 000000000..a66cf36cc
--- /dev/null
+++ b/vendor/zeroize/src/x86.rs
@@ -0,0 +1,40 @@
+//! [`Zeroize`] impls for x86 SIMD registers
+
+use crate::{atomic_fence, volatile_write, Zeroize};
+
+#[cfg(target_arch = "x86")]
+use core::arch::x86::*;
+
+#[cfg(target_arch = "x86_64")]
+use core::arch::x86_64::*;
+
+macro_rules! impl_zeroize_for_simd_register {
+ ($type:ty, $feature:expr, $zero_value:ident) => {
+ #[cfg_attr(docsrs, doc(cfg(target_arch = "x86")))] // also `x86_64`
+ #[cfg_attr(docsrs, doc(cfg(target_feature = $feature)))]
+ impl Zeroize for $type {
+ fn zeroize(&mut self) {
+ volatile_write(self, unsafe { $zero_value() });
+ atomic_fence();
+ }
+ }
+ };
+}
+
+#[cfg(target_feature = "sse")]
+impl_zeroize_for_simd_register!(__m128, "sse", _mm_setzero_ps);
+
+#[cfg(target_feature = "sse2")]
+impl_zeroize_for_simd_register!(__m128d, "sse2", _mm_setzero_pd);
+
+#[cfg(target_feature = "sse2")]
+impl_zeroize_for_simd_register!(__m128i, "sse2", _mm_setzero_si128);
+
+#[cfg(target_feature = "avx")]
+impl_zeroize_for_simd_register!(__m256, "avx", _mm256_setzero_ps);
+
+#[cfg(target_feature = "avx")]
+impl_zeroize_for_simd_register!(__m256d, "avx", _mm256_setzero_pd);
+
+#[cfg(target_feature = "avx")]
+impl_zeroize_for_simd_register!(__m256i, "avx", _mm256_setzero_si256);
diff --git a/vendor/zeroize/tests/zeroize.rs b/vendor/zeroize/tests/zeroize.rs
new file mode 100644
index 000000000..32281c1c1
--- /dev/null
+++ b/vendor/zeroize/tests/zeroize.rs
@@ -0,0 +1,210 @@
+//! zeroize integration tests.
+
+use std::{
+ marker::{PhantomData, PhantomPinned},
+ mem::{size_of, MaybeUninit},
+ num::*,
+};
+use zeroize::*;
+
+#[cfg(feature = "std")]
+use std::ffi::CString;
+
+#[derive(Clone, Debug, PartialEq)]
+struct ZeroizedOnDrop(u64);
+
+impl Drop for ZeroizedOnDrop {
+ fn drop(&mut self) {
+ self.0.zeroize();
+ }
+}
+
+#[test]
+fn non_zero() {
+ macro_rules! non_zero_test {
+ ($($type:ty),+) => {
+ $(let mut value = <$type>::new(42).unwrap();
+ value.zeroize();
+ assert_eq!(value.get(), 1);)+
+ };
+ }
+
+ non_zero_test!(
+ NonZeroI8,
+ NonZeroI16,
+ NonZeroI32,
+ NonZeroI64,
+ NonZeroI128,
+ NonZeroIsize,
+ NonZeroU8,
+ NonZeroU16,
+ NonZeroU32,
+ NonZeroU64,
+ NonZeroU128,
+ NonZeroUsize
+ );
+}
+
+#[test]
+fn zeroize_byte_arrays() {
+ let mut arr = [42u8; 137];
+ arr.zeroize();
+ assert_eq!(arr.as_ref(), [0u8; 137].as_ref());
+}
+
+#[test]
+fn zeroize_on_drop_byte_arrays() {
+ let mut arr = [ZeroizedOnDrop(42); 1];
+ unsafe { core::ptr::drop_in_place(&mut arr) };
+ assert_eq!(arr.as_ref(), [ZeroizedOnDrop(0); 1].as_ref());
+}
+
+#[test]
+fn zeroize_maybeuninit_byte_arrays() {
+ let mut arr = [MaybeUninit::new(42u64); 64];
+ arr.zeroize();
+ let arr_init: [u64; 64] = unsafe { core::mem::transmute(arr) };
+ assert_eq!(arr_init, [0u64; 64]);
+}
+
+#[test]
+fn zeroize_check_zerosize_types() {
+ // Since we assume these types have zero size, we test this holds for
+ // the current version of Rust.
+ assert_eq!(size_of::<()>(), 0);
+ assert_eq!(size_of::<PhantomPinned>(), 0);
+ assert_eq!(size_of::<PhantomData<usize>>(), 0);
+}
+
+#[test]
+fn zeroize_check_tuple() {
+ let mut tup1 = (42u8,);
+ tup1.zeroize();
+ assert_eq!(tup1, (0u8,));
+
+ let mut tup2 = (42u8, 42u8);
+ tup2.zeroize();
+ assert_eq!(tup2, (0u8, 0u8));
+}
+
+#[test]
+fn zeroize_on_drop_check_tuple() {
+ let mut tup1 = (ZeroizedOnDrop(42),);
+ unsafe { core::ptr::drop_in_place(&mut tup1) };
+ assert_eq!(tup1, (ZeroizedOnDrop(0),));
+
+ let mut tup2 = (ZeroizedOnDrop(42), ZeroizedOnDrop(42));
+ unsafe { core::ptr::drop_in_place(&mut tup2) };
+ assert_eq!(tup2, (ZeroizedOnDrop(0), ZeroizedOnDrop(0)));
+}
+
+#[cfg(feature = "alloc")]
+#[test]
+fn zeroize_vec() {
+ let mut vec = vec![42; 3];
+ vec.zeroize();
+ assert!(vec.is_empty());
+}
+
+#[cfg(feature = "alloc")]
+#[test]
+fn zeroize_vec_entire_capacity() {
+ #[derive(Clone)]
+ struct PanicOnNonZeroDrop(u64);
+
+ impl Zeroize for PanicOnNonZeroDrop {
+ fn zeroize(&mut self) {
+ self.0 = 0;
+ }
+ }
+
+ impl Drop for PanicOnNonZeroDrop {
+ fn drop(&mut self) {
+ if self.0 != 0 {
+ panic!("dropped non-zeroized data");
+ }
+ }
+ }
+
+ // Ensure that the entire capacity of the vec is zeroized and that no unitinialized data
+ // is ever interpreted as initialized
+ let mut vec = vec![PanicOnNonZeroDrop(42); 2];
+
+ unsafe {
+ vec.set_len(1);
+ }
+
+ vec.zeroize();
+
+ unsafe {
+ vec.set_len(2);
+ }
+
+ drop(vec);
+}
+
+#[cfg(feature = "alloc")]
+#[test]
+fn zeroize_string() {
+ let mut string = String::from("Hello, world!");
+ string.zeroize();
+ assert!(string.is_empty());
+}
+
+#[cfg(feature = "alloc")]
+#[test]
+fn zeroize_string_entire_capacity() {
+ let mut string = String::from("Hello, world!");
+ string.truncate(5);
+
+ string.zeroize();
+
+ // convert the string to a vec to easily access the unused capacity
+ let mut as_vec = string.into_bytes();
+ unsafe { as_vec.set_len(as_vec.capacity()) };
+
+ assert!(as_vec.iter().all(|byte| *byte == 0));
+}
+
+// TODO(tarcieri): debug flaky test (with potential UB?) See: RustCrypto/utils#774
+#[cfg(feature = "std")]
+#[ignore]
+#[test]
+fn zeroize_c_string() {
+ let mut cstring = CString::new("Hello, world!").expect("CString::new failed");
+ let orig_len = cstring.as_bytes().len();
+ let orig_ptr = cstring.as_bytes().as_ptr();
+ cstring.zeroize();
+ // This doesn't quite test that the original memory has been cleared, but only that
+ // cstring now owns an empty buffer
+ assert!(cstring.as_bytes().is_empty());
+ for i in 0..orig_len {
+ unsafe {
+ // Using a simple deref, only one iteration of the loop is performed
+ // presumably because after zeroize, the internal buffer has a length of one/
+ // `read_volatile` seems to "fix" this
+ // Note that this is very likely UB
+ assert_eq!(orig_ptr.add(i).read_volatile(), 0);
+ }
+ }
+}
+
+#[cfg(feature = "alloc")]
+#[test]
+fn zeroize_box() {
+ let mut boxed_arr = Box::new([42u8; 3]);
+ boxed_arr.zeroize();
+ assert_eq!(boxed_arr.as_ref(), &[0u8; 3]);
+}
+
+#[cfg(feature = "alloc")]
+#[test]
+fn asref() {
+ let mut buffer: Zeroizing<Vec<u8>> = Default::default();
+ let _asmut: &mut [u8] = buffer.as_mut();
+ let _asref: &[u8] = buffer.as_ref();
+
+ let mut buffer: Zeroizing<Box<[u8]>> = Default::default();
+ let _asmut: &mut [u8] = buffer.as_mut();
+ let _asref: &[u8] = buffer.as_ref();
+}
diff --git a/vendor/zeroize/tests/zeroize_derive.rs b/vendor/zeroize/tests/zeroize_derive.rs
new file mode 100644
index 000000000..4e0fdc61c
--- /dev/null
+++ b/vendor/zeroize/tests/zeroize_derive.rs
@@ -0,0 +1,317 @@
+//! Integration tests for `zeroize_derive` proc macros
+#![cfg(feature = "zeroize_derive")]
+
+use zeroize::{Zeroize, ZeroizeOnDrop};
+
+#[test]
+fn derive_tuple_struct_test() {
+ #[derive(Zeroize, ZeroizeOnDrop)]
+ struct Z([u8; 3]);
+
+ let mut value = Z([1, 2, 3]);
+ value.zeroize();
+ assert_eq!(&value.0, &[0, 0, 0])
+}
+
+#[test]
+#[cfg(feature = "alloc")]
+fn derive_struct_test() {
+ #[derive(Zeroize, ZeroizeOnDrop)]
+ struct Z {
+ string: String,
+ vec: Vec<u8>,
+ bytearray: [u8; 3],
+ number: usize,
+ boolean: bool,
+ }
+
+ let mut value = Z {
+ string: String::from("Hello, world!"),
+ vec: vec![1, 2, 3],
+ bytearray: [4, 5, 6],
+ number: 42,
+ boolean: true,
+ };
+
+ value.zeroize();
+
+ assert!(value.string.is_empty());
+ assert!(value.vec.is_empty());
+ assert_eq!(&value.bytearray, &[0, 0, 0]);
+ assert_eq!(value.number, 0);
+ assert!(!value.boolean);
+}
+
+#[test]
+fn derive_enum_test() {
+ #[derive(Zeroize, ZeroizeOnDrop)]
+ enum Z {
+ #[allow(dead_code)]
+ Variant1,
+ Variant2(usize),
+ }
+
+ let mut value = Z::Variant2(26);
+
+ value.zeroize();
+
+ assert!(matches!(value, Z::Variant2(0)));
+}
+
+/// Test that the custom macro actually derived `Drop` for `Z`
+#[test]
+fn derive_struct_drop() {
+ #[derive(Zeroize, ZeroizeOnDrop)]
+ struct Z([u8; 3]);
+
+ assert!(std::mem::needs_drop::<Z>());
+}
+
+/// Test that the custom macro actually derived `Drop` for `Z`
+#[test]
+fn derive_enum_drop() {
+ #[allow(dead_code)]
+ #[derive(Zeroize, ZeroizeOnDrop)]
+ enum Z {
+ Variant1,
+ Variant2(usize),
+ }
+
+ assert!(std::mem::needs_drop::<Z>());
+}
+
+/// Test that the custom macro actually derived `Drop` for `Z`
+#[test]
+fn derive_struct_only_drop() {
+ #[derive(ZeroizeOnDrop)]
+ struct Z([u8; 3]);
+
+ assert!(std::mem::needs_drop::<Z>());
+}
+
+/// Test that the custom macro actually derived `Drop` for `Z`
+#[test]
+fn derive_enum_only_drop() {
+ #[allow(dead_code)]
+ #[derive(ZeroizeOnDrop)]
+ enum Z {
+ Variant1,
+ Variant2(usize),
+ }
+
+ assert!(std::mem::needs_drop::<Z>());
+}
+
+/// Test that `Drop` is not derived in the following case by defining a
+/// `Drop` impl which should conflict if the custom derive defined one too
+#[allow(dead_code)]
+#[derive(Zeroize)]
+struct ZeroizeNoDropStruct([u8; 3]);
+
+impl Drop for ZeroizeNoDropStruct {
+ fn drop(&mut self) {}
+}
+
+#[allow(dead_code)]
+#[derive(Zeroize)]
+enum ZeroizeNoDropEnum {
+ Variant([u8; 3]),
+}
+
+impl Drop for ZeroizeNoDropEnum {
+ fn drop(&mut self) {}
+}
+
+#[test]
+#[cfg(feature = "alloc")]
+fn derive_struct_skip() {
+ #[derive(Zeroize, ZeroizeOnDrop)]
+ struct Z {
+ string: String,
+ vec: Vec<u8>,
+ #[zeroize(skip)]
+ bytearray: [u8; 3],
+ number: usize,
+ boolean: bool,
+ }
+
+ let mut value = Z {
+ string: String::from("Hello, world!"),
+ vec: vec![1, 2, 3],
+ bytearray: [4, 5, 6],
+ number: 42,
+ boolean: true,
+ };
+
+ value.zeroize();
+
+ assert!(value.string.is_empty());
+ assert!(value.vec.is_empty());
+ assert_eq!(&value.bytearray, &[4, 5, 6]);
+ assert_eq!(value.number, 0);
+ assert!(!value.boolean);
+}
+
+#[test]
+#[cfg(feature = "alloc")]
+fn derive_enum_skip() {
+ #[derive(Zeroize, ZeroizeOnDrop)]
+ enum Z {
+ #[allow(dead_code)]
+ Variant1,
+ #[zeroize(skip)]
+ Variant2([u8; 3]),
+ #[zeroize(skip)]
+ Variant3 {
+ string: String,
+ vec: Vec<u8>,
+ bytearray: [u8; 3],
+ number: usize,
+ boolean: bool,
+ },
+ Variant4 {
+ string: String,
+ vec: Vec<u8>,
+ #[zeroize(skip)]
+ bytearray: [u8; 3],
+ number: usize,
+ boolean: bool,
+ },
+ }
+
+ let mut value = Z::Variant2([4, 5, 6]);
+
+ value.zeroize();
+
+ assert!(matches!(&value, Z::Variant2([4, 5, 6])));
+
+ let mut value = Z::Variant3 {
+ string: String::from("Hello, world!"),
+ vec: vec![1, 2, 3],
+ bytearray: [4, 5, 6],
+ number: 42,
+ boolean: true,
+ };
+
+ value.zeroize();
+
+ assert!(matches!(
+ &value,
+ Z::Variant3 { string, vec, bytearray, number, boolean }
+ if string == "Hello, world!" &&
+ vec == &[1, 2, 3] &&
+ bytearray == &[4, 5, 6] &&
+ *number == 42 &&
+ *boolean
+ ));
+
+ let mut value = Z::Variant4 {
+ string: String::from("Hello, world!"),
+ vec: vec![1, 2, 3],
+ bytearray: [4, 5, 6],
+ number: 42,
+ boolean: true,
+ };
+
+ value.zeroize();
+
+ assert!(matches!(
+ &value,
+ Z::Variant4 { string, vec, bytearray, number, boolean }
+ if string.is_empty() &&
+ vec.is_empty() &&
+ bytearray == &[4, 5, 6] &&
+ *number == 0 &&
+ !boolean
+ ));
+}
+
+#[test]
+fn derive_bound() {
+ trait T: Zeroize {}
+
+ impl T for u8 {}
+
+ #[derive(Zeroize)]
+ #[zeroize(bound = "X: T")]
+ struct Z<X>(X);
+
+ let mut value = Z(5_u8);
+
+ value.zeroize();
+
+ assert_eq!(value.0, 0);
+}
+
+#[test]
+fn derive_inherit_zeroize_on_drop() {
+ #[derive(ZeroizeOnDrop)]
+ struct X([u8; 3]);
+
+ #[derive(ZeroizeOnDrop)]
+ struct Z(X);
+
+ let mut value = Z(X([1, 2, 3]));
+ unsafe {
+ std::ptr::drop_in_place(&mut value);
+ }
+ assert_eq!(&value.0 .0, &[0, 0, 0])
+}
+
+#[test]
+fn derive_inherit_from_both() {
+ #[derive(Zeroize, ZeroizeOnDrop)]
+ struct X([u8; 3]);
+
+ #[derive(ZeroizeOnDrop)]
+ struct Z(X);
+
+ let mut value = Z(X([1, 2, 3]));
+ unsafe {
+ std::ptr::drop_in_place(&mut value);
+ }
+ assert_eq!(&value.0 .0, &[0, 0, 0])
+}
+
+#[test]
+fn derive_inherit_both() {
+ #[derive(Zeroize, ZeroizeOnDrop)]
+ struct X([u8; 3]);
+
+ #[derive(Zeroize, ZeroizeOnDrop)]
+ struct Z(X);
+
+ let mut value = Z(X([1, 2, 3]));
+ unsafe {
+ std::ptr::drop_in_place(&mut value);
+ }
+ assert_eq!(&value.0 .0, &[0, 0, 0])
+}
+
+#[test]
+fn derive_deref() {
+ struct X([u8; 3]);
+
+ impl std::ops::Deref for X {
+ type Target = [u8];
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+ }
+
+ impl std::ops::DerefMut for X {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.0
+ }
+ }
+
+ #[derive(Zeroize, ZeroizeOnDrop)]
+ struct Z(X);
+
+ let mut value = Z(X([1, 2, 3]));
+ unsafe {
+ std::ptr::drop_in_place(&mut value);
+ }
+ assert_eq!(&value.0 .0, &[0, 0, 0])
+}