Skip to content

Commit fc7518b

Browse files
authored
Merge pull request #1517 from sporksmith/openssl-drbg
Openssl drbg Adapted from shadow-plugin-tor. I only took the RNG overrides, since those seemed generic enough to plausibly work with other programs besides tor. Not sure whether we'll want the "nop crypto" overrides as well, but if so it should probably be able to be used independently of the RNG overrides; e.g. by putting them in a separate library. Progress on #666
2 parents fa95047 + 40ea8b5 commit fc7518b

5 files changed

Lines changed: 141 additions & 0 deletions

File tree

docs/getting_started_tor.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,25 @@ You can use the [tornettools
3434
toolkit](https://github.com/shadow/tornettools) to run larger, more
3535
complex Tor networks that are meant to more accurately resemble the
3636
characteristics and state of the public Tor network.
37+
38+
## Determinism
39+
40+
Shadow isn't able to natively intercept all sources entropy that tor uses via
41+
openssl, which results in non-deterministic results. If you'd like better
42+
determinism for your simulation, you can use the provided auxiliary library,
43+
libshadow_openssl_rng, whichoverride's some of openssl's RNG routines.
44+
45+
To do so, add the full path to the library to the `LD_PRELOAD` in each tor
46+
process's `environment`. If you've installed Shadow to the default location,
47+
the path should be `home/<username>/.local/lib/libshadow_openssl_rng.so`.
48+
49+
```
50+
...
51+
hosts:
52+
torclient:
53+
processes:
54+
- path: ~/.local/bin/tor
55+
# Must provide absolute path. See #1523.
56+
environment: 'LD_PRELOAD=/home/<username>/.local/lib/libshadow_openssl_rng.so'
57+
...
58+
```

src/lib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
add_subdirectory(logger)
2+
add_subdirectory(openssl_preload)
23
add_subdirectory(tsc)
34
add_subdirectory(shim)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
add_library(shadow_openssl_rng SHARED shadow_openssl_rng.c)
2+
target_compile_options(shadow_openssl_rng PRIVATE -D_GNU_SOURCE -fPIC)
3+
install(TARGETS shadow_openssl_rng DESTINATION lib)
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* The Shadow Simulator
3+
* Copyright (c) 2010-2011, Rob Jansen
4+
* See LICENSE for licensing information
5+
*/
6+
7+
/* Implements an LD_PRELOAD library intended for use with Shadow. libcrypto
8+
* otherwise internally uses some entropy sources that Shadow is unable to trap
9+
* and emulate (such as the RDRAND instruction), making Shadow simulations of
10+
* software using libcrypto non-deterministic.
11+
*
12+
* To use this library, set LD_PRELOAD in the target program's `environment`
13+
* attribute in the Shadow simulation config file. e.g.:
14+
*
15+
* hosts:
16+
* torclient:
17+
* processes:
18+
* - path: ~/.local/bin/tor
19+
* # Must provide absolute path. See #1523.
20+
* environment: 'LD_PRELOAD=/home/<username>/.local/lib/libshadow_openssl_rng.so'
21+
*/
22+
23+
#include <stddef.h>
24+
#include <sys/syscall.h>
25+
#include <unistd.h>
26+
27+
static int _getRandomBytes(unsigned char* buf, int numBytes) {
28+
// shadow interposes this and will fill the buffer for us
29+
// return 1 on success, 0 otherwise
30+
return (numBytes == syscall(SYS_getrandom, buf, (size_t)numBytes, 0)) ? 1 : 0;
31+
}
32+
33+
int RAND_DRBG_generate(void *drbg,
34+
unsigned char *out, size_t outlen,
35+
int prediction_resistance,
36+
const unsigned char *adin, size_t adinlen) {
37+
return _getRandomBytes(out, outlen);
38+
}
39+
40+
int RAND_DRBG_bytes(void *drbg,
41+
unsigned char *out, size_t outlen) {
42+
return _getRandomBytes(out, outlen);
43+
}
44+
45+
int RAND_bytes(unsigned char *buf, int num) {
46+
return _getRandomBytes(buf, num);
47+
}
48+
49+
int RAND_pseudo_bytes(unsigned char *buf, int num) {
50+
return _getRandomBytes(buf, num);
51+
}
52+
53+
void RAND_seed(const void *buf, int num) {
54+
return;
55+
}
56+
57+
void RAND_add(const void *buf, int num, double entropy) {
58+
return;
59+
}
60+
61+
int RAND_poll() {
62+
return 1;
63+
}
64+
65+
void RAND_cleanup(void) {
66+
return;
67+
}
68+
69+
int RAND_status(void) {
70+
return 1;
71+
}
72+
73+
// Callback return type changed from void to int in OpenSSL_1_1_0-pre1.
74+
// However, since x86-64 uses rax for return values, and rax is a caller-saved
75+
// register, it's safe to return an int even if the caller is expecting void.
76+
static int nop_seed(const void* buf, int num) { return 1; }
77+
78+
// Callback return type changed from void to int, and entropy from int to to
79+
// double in OpenSSL_1_1_0-pre1.
80+
//
81+
// However, since x86-64 uses rax for return values, and rax is a caller-saved
82+
// register, it's safe to return an int even if the caller is expecting void.
83+
// Similarly, since we don't actually use either parameter, it doesn't matter if
84+
// the types match.
85+
static int nop_add(const void* buf, int num, double entropy) { return 1; }
86+
87+
typedef struct {
88+
int (*seed)(const void* buf, int num);
89+
int (*bytes)(unsigned char* buf, int num);
90+
void (*cleanup)(void);
91+
int (*add)(const void* buf, int num, double entropy);
92+
int (*pseudorand)(unsigned char* buf, int num);
93+
int (*status)(void);
94+
} RAND_METHOD;
95+
96+
const RAND_METHOD* RAND_get_rand_method() {
97+
static const RAND_METHOD method = {
98+
.seed = nop_seed,
99+
.bytes = RAND_bytes,
100+
.cleanup = RAND_cleanup,
101+
.add = nop_add,
102+
.pseudorand = RAND_pseudo_bytes,
103+
.status = RAND_status,
104+
};
105+
return &method;
106+
}

src/test/tor/minimal/tor-minimal.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ hosts:
3333
args: ../../../conf/tgen.hiddenserver.graphml.xml
3434
start_time: 1
3535
- path: ~/.local/bin/tor
36+
environment: 'LD_PRELOAD=../../../../../../lib/openssl_preload/libshadow_openssl_rng.so'
3637
args: --Address hiddenserver --Nickname hiddenserver
3738
--defaults-torrc torrc-defaults -f torrc
3839
start_time: 900
@@ -41,30 +42,35 @@ hosts:
4142
ip_address_hint: 100.0.0.1
4243
processes:
4344
- path: ~/.local/bin/tor
45+
environment: 'LD_PRELOAD=../../../../../../lib/openssl_preload/libshadow_openssl_rng.so'
4446
args: --Address 4uthority --Nickname 4uthority
4547
--defaults-torrc torrc-defaults -f torrc
4648
start_time: 1
4749
exit1:
4850
processes:
4951
- path: ~/.local/bin/tor
52+
environment: 'LD_PRELOAD=../../../../../../lib/openssl_preload/libshadow_openssl_rng.so'
5053
args: --Address exit1 --Nickname exit1
5154
--defaults-torrc torrc-defaults -f torrc
5255
start_time: 60
5356
exit2:
5457
processes:
5558
- path: ~/.local/bin/tor
59+
environment: 'LD_PRELOAD=../../../../../../lib/openssl_preload/libshadow_openssl_rng.so'
5660
args: --Address exit2 --Nickname exit2
5761
--defaults-torrc torrc-defaults -f torrc
5862
start_time: 60
5963
relay1:
6064
processes:
6165
- path: ~/.local/bin/tor
66+
environment: 'LD_PRELOAD=../../../../../../lib/openssl_preload/libshadow_openssl_rng.so'
6267
args: --Address relay1 --Nickname relay1
6368
--defaults-torrc torrc-defaults -f torrc
6469
start_time: 60
6570
relay2:
6671
processes:
6772
- path: ~/.local/bin/tor
73+
environment: 'LD_PRELOAD=../../../../../../lib/openssl_preload/libshadow_openssl_rng.so'
6874
args: --Address relay2 --Nickname relay2
6975
--defaults-torrc torrc-defaults -f torrc
7076
start_time: 60
@@ -76,6 +82,7 @@ hosts:
7682
torclient:
7783
processes:
7884
- path: ~/.local/bin/tor
85+
environment: 'LD_PRELOAD=../../../../../../lib/openssl_preload/libshadow_openssl_rng.so'
7986
args: --Address torclient --Nickname torclient
8087
--defaults-torrc torrc-defaults -f torrc
8188
start_time: 900
@@ -85,6 +92,7 @@ hosts:
8592
torbridgeclient:
8693
processes:
8794
- path: ~/.local/bin/tor
95+
environment: 'LD_PRELOAD=../../../../../../lib/openssl_preload/libshadow_openssl_rng.so'
8896
args: --Address torbridgeclient --Nickname torbridgeclient
8997
--UseBridges 1 --Bridge 100.0.0.1:9111
9098
--defaults-torrc torrc-defaults -f torrc
@@ -95,6 +103,7 @@ hosts:
95103
torhiddenclient:
96104
processes:
97105
- path: ~/.local/bin/tor
106+
environment: 'LD_PRELOAD=../../../../../../lib/openssl_preload/libshadow_openssl_rng.so'
98107
args: --Address torhiddenclient --Nickname torhiddenclient
99108
--defaults-torrc torrc-defaults -f torrc
100109
start_time: 900

0 commit comments

Comments
 (0)