# Using crates.io dependencies (EDP) https://edp.fortanix.com/docs/tasks/dependencies/ Links: [[EDP]], [[SGX]] It is highly likely that your crate depends (directly or transitively) on crates published on [crates.io](https://crates.io/). Oftentimes, compiling your dependencies for the `x86_64-fortanix-unknown-sgx` target will just work. Sometimes, you may see that a dependency doesn't compile due to a missing implementation for this target. This can happen if the crate uses platform-specific functionality or links to code written in other languages. You will need to add an implementation for the SGX target to the crate in question. ## Example: `rand` Let's understand this with the help of an example, an old version of the `rand` crate. (The `rand` crate has already been ported to SGX, the latest 0.4 and 0.6 versions will work out of the box.) - Create a new crate ```bash cargo new port_test ``` - Add `rand (v0.4.5)` as dependency to this crate Append following lines to `Cargo.toml`: ```toml [dependencies] rand = "=0.4.5" ``` - Compile the crate ```bash cargo build ``` - Realize the compilation failure reason You may see following output (or something similar) for `cargo build` ``` Compiling rand v0.4.5 (<path>/rand) error[E0433]: failed to resolve: use of undeclared type or module `imp` --> <path>/rand/src/os.rs:35:18 | 35 | pub struct OsRng(imp::OsRng); | ^^^ use of undeclared type or module `imp` error[E0433]: failed to resolve: use of undeclared type or module `imp` --> <path>/rand/src/os.rs:40:9 | 40 | imp::OsRng::new().map(OsRng) | ^^^ use of undeclared type or module `imp` ``` The output states that module `imp` is missing for SGX target. The type `OsRng` is missing as well. ## Implement To add an implementation for a specific target, you can use [conditional compilation](https://doc.rust-lang.org/stable/reference/conditional-compilation.html). The proper way to conditionally compile for `x86_64-fortanix-unknown-sgx` is with `cfg(all(target_env = "sgx", target_vendor = "fortanix"))`. Let's take a look at the implementation needed for `rand`. Setup a copy of the rand [source](https://github.com/rust-random/rand). Checkout the relevant branch, `0.4` in this case. Append following lines in `src/lib.rs`: ```rust #[cfg(all(target_env = "sgx", target_vendor = "fortanix"))] mod imp { use rdrand::RdRand; use std::io; use rand_core::RngCore; pub struct OsRng{ gen: RdRand } impl OsRng { pub fn new() -> io::Result<OsRng> { match RdRand::new() { Ok(rng) => Ok(OsRng { gen: rng }), Err(_) => Err(io::Error::new(io::ErrorKind::Other, "Not supported")) } } pub(crate) fn next_u32(&mut self) -> u32 { match self.gen.try_next_u32() { Some(n) => n, None => panic!("Non-recoverable hardware failure has occurred") } } pub(crate) fn next_u64(&mut self) -> u64 { match self.gen.try_next_u64() { Some(n) => n, None => panic!("Non-recoverable hardware failure has occurred") } } pub(crate) fn fill_bytes(&mut self, v: &mut [u8]) { match self.gen.try_fill_bytes(v) { Ok(_) => {}, Err(_) => panic!("Non-recoverable hardware failure has occurred") } } } } ``` Here's the [link](https://github.com/rust-random/rand/pull/680/files) to actual implementation. ## Test You can test your changes by [overriding the dependency](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#overriding-dependencies) with your copy. Append following lines to Cargo.toml: ```toml [patch.crates-io] rand = { path = "<path-to-your-copy-of-dependency>" } ``` Alternatively, you can add below lines if you want to pick changes from a git repo: ```toml [patch.crates-io] rand = { git="<git-repo-name>", branch="<branch-name>" } ``` You should be able to compile successfully (assuming your changes are correct and sufficient): ```bash cargo build ``` ## Push changes to upstream It is highly recommended that you push your changes to upstream. ### Create a Pull Request in the original repo for your changes Create a Pull Request on the relevant branch in the original repo for your changes. Add a meaningful title to the PR, e.g. `"Add support for x86_64-fortanix-unknown-sgx target"` ### Ask us to review You can always ping us to review your changes. We highly appreciate your contribution. **Note:** Once your changes get merged in original dependency git repo, you should remove the patch section from Cargo.toml .