# 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 .