1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
//! This crate provides friendly and idiomatic Rust wrappers over [SymCrypt](https://github.com/microsoft/SymCrypt), an open-source cryptographic library.
//!
//! This crate has a dependency on `symcrypt-sys`, which utilizes `bindgen` to create `Rust/C` FFI bindings.
//!
//! **Note:** As of version 0.1.0, only Windows AMD64(x86_64) is supported.
//!
//! ## Installation
//!
//! To use the SymCrypt crate, you must have a local version of [SymCrypt](https://github.com/microsoft/SymCrypt) downloaded.
//!
//! Please follow the [Build Instructions](https://github.com/microsoft/SymCrypt/blob/main/BUILD.md) that is provided by SymCrypt to install SymCrypt for your target architecture.
//!
//! Once SymCrypt is installed and built locally on your machine, we must configure your machine so that the SymCrypt crate's build script can easily find `symcrypttestmodule.dll` and `symcrypttestmodule.lib`
//! which are both requirements for the SymCrypt crate.
//!
//!
//! ### Configure symcrypttestmodule.lib location
//! The `symcrypttestmodule.lib` can be found in the the following path after SymCrypt has been successfully downloaded and built.
//!
//! `C:\Your-Path-To-SymCrypt\SymCrypt\bin\lib`
//!
//! The SymCrypt crate needs a static lib to link to during its build/link time. You must configure your system so that the SymCrypt crate's build script can easily find the needed `symcrypttestmodule.lib` file.
//!
//! You can configure your system one of 3 ways.
//!
//! 1. Add the lib path as a one time cargo environment variable.
//! ```powershell
//! $env:RUSTFLAGS='-L C:\Your-Path-To-SymCrypt\SymCrypt\bin\lib'
//! ```
//!
//! **Note:** This change will only persist within the current process, and you must re-set the PATH environment variable after closing the PowerShell window.
//!
//! 2. Manually copy the `symcrypttestmodule.lib` to `C:\Windows\System32`
//! Doing this will ensure that any project that uses the SymCrypt crate will be able to access `symcrypttestmodule.lib`
//!
//! 3. Permanently add the lib path into as a new system environment variable. Doing this will ensure that any project that uses the SymCrypt crate will be able to access `symcrypttestmodule.lib`
//!
//! **Option 1 or Option 2 is what is recommended for ease of use.**
//!
//! ### Configure symcrypttesmodule.dll location
//!
//! The symcrypttestmodule.dll can be found in the the following path after SymCrypt has been successfully downloaded and built.
//!
//! `C:\Your-Path-To-SymCrypt\SymCrypt\bin\exe`
//!
//! During runtime, Windows will handle finding all needed `dll`'s in order to run the intended program, this includes our `symcrypttestmodule.dll` file. The places Windows will look are:
//!
//! 1. The folder from which the application loaded.
//! 2. The system folder. Use the `GetSystemDirectory` function to retrieve the path of this folder.
//! 3. The Windows folder. Use the `GetWindowsDirectory` function to get the path of this folder.
//! 4. The current folder.
//! 5. The directories listed in the PATH environment variable.
//!
//! For more info please see: [Dynamic-link library search order](https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order)
//!
//!
//! Here are 4 recommended options to ensure your `symcrypttestmodule.dll` is found by Windows during runtime.
//!
//! 1. Put the symcrypttesmodule.dll in the same folder as your output `.exe` file. If you are doing development (not release), the common path will be: `C:\your-project\target\debug\`.
//!
//! 2. Add the symcrypttestmoudle.dll path as a one time environment variable.
//! ```powershell
//! $env:PATH = "C:\Your-Path-To-SymCrypt\SymCrypt\bin\exe;$env:PATH"
//! ```
//! **Note:** This change will only persist within the current process, and you must re-set the PATH environment variable after closing the PowerShell window.
//!
//! 3. Manually copy `symcrypttestmodule.dll` into your `C:/Windows/System32/`
//! Doing this will ensure that any project that uses the SymCrypt crate will be able to access `symcrypttestmodule.dll`
//!
//! 4. Permanently add the `symcrypttestmodule.dll` path into your System PATH environment variable.
//! Doing this will ensure that any project that uses the SymCrypt crate will be able to access `symcrypttestmodule.lib`
//!
//! **Option 3 or Option 4 is what is recommended for ease of use.**
//!
//! ## Supported APIs
//! Hashing:
//! - Sha256 ( statefull/stateless )
//! - Sha384 ( statefull/stateless )
//!
//! HMAC:
//! - HmacSha256 ( statefull/stateless )
//! - HmacSha384 ( statefull/stateless )
//!
//! GCM:
//! - Encryption ( in place )
//! - Decryption ( in place )
//!
//! ChaCha:
//! - Encryption ( in place )
//! - Decryption ( in place )
//!
//! ECDH:
//! - ECDH Secret Agreement
//!
//! ## Usage
//! There are unit tests attached to each file that show how to use each function. Included is some sample code to do a stateless Sha256 hash. `symcrypt_init()` must be run before any other calls to the underlying symcrypt code.
//!
//! **Note:** This code snippet also uses the [hex](https://crates.io/crates/hex) crate.
//!
//! ### Instructions:
//!
//! add symcrypt to your `Cargo.toml` file.
//!
//!
//! `symcrypt = "0.1.0"`
//!
//!
//! include symcrypt in your code
//!
//! ```rust
//! use symcrypt::hash::sha256;
//! use symcrypt::symcrypt_init;
//!
//! fn main() {
//! symcrypt_init();
//! let data = hex::decode("641ec2cf711e").unwrap();
//! let expected: &str = "cfdbd6c9acf9842ce04e8e6a0421838f858559cf22d2ea8a38bd07d5e4692233";
//!
//! let result = sha256(&data);
//! assert_eq!(hex::encode(result), expected);
//! }
//! ```
use std::sync::Once;
/// `symcrypt_init()` must be called before any other function in the library. `symcrypt_init()` can be called multiple times,
/// all subsequent calls will be no-ops
pub fn symcrypt_init() {
// Subsequent calls to `symcrypt_init()` after the first will not be invoked per .call_once docs https://doc.rust-lang.org/std/sync/struct.Once.html
static INIT: Once = Once::new();
unsafe {
// SAFETY: FFI calls, blocking from being run again.
INIT.call_once(|| {
symcrypt_sys::SymCryptModuleInit(
symcrypt_sys::SYMCRYPT_CODE_VERSION_API,
symcrypt_sys::SYMCRYPT_CODE_VERSION_MINOR,
)
});
}
}
/// Takes in a `rand_length` and returns a [`Vec<u8>`] with `rand_length` random bytes
pub fn symcrypt_random(rand_length: u64) -> Vec<u8> {
let mut random_buffer: Vec<u8> = vec![0; rand_length as usize];
unsafe {
// SAFETY: FFI calls
symcrypt_sys::SymCryptRandom(random_buffer.as_mut_ptr(), rand_length);
}
random_buffer
}
pub mod block_ciphers;
pub mod chacha;
pub mod ecdh;
pub mod eckey;
pub mod errors;
pub mod gcm;
pub mod hash;
pub mod hmac;