Integrate Kyber1024 client/server communication into SVR*.
This commit is contained in:
parent
30a96d58f0
commit
5908542cf8
2
.github/workflows/push.yml
vendored
2
.github/workflows/push.yml
vendored
@ -20,7 +20,7 @@ jobs:
|
||||
- name: Checkout main project
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
submodules: true
|
||||
submodules: recursive
|
||||
lfs: true
|
||||
|
||||
- name: Show releases
|
||||
|
||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
||||
- name: Checkout main project
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
submodules: true
|
||||
submodules: recursive
|
||||
|
||||
- name: Expose Docker environmental variables for gha cache
|
||||
# This action takes in the ID tokens etc provided by the permissions,
|
||||
|
||||
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -3,7 +3,7 @@
|
||||
url = https://github.com/protocolbuffers/protobuf.git
|
||||
[submodule "enclave/noise-c"]
|
||||
path = enclave/noise-c
|
||||
url = https://github.com/rweather/noise-c.git
|
||||
url = https://github.com/signalapp/noise-c.git
|
||||
[submodule "enclave/SipHash"]
|
||||
path = enclave/SipHash
|
||||
url = https://github.com/veorq/SipHash
|
||||
|
||||
3
Makefile
3
Makefile
@ -16,7 +16,8 @@ validate:
|
||||
|
||||
git:
|
||||
git submodule init || true
|
||||
git submodule update || true
|
||||
git submodule update --recursive --init || true
|
||||
git submodule update --recursive || true
|
||||
|
||||
ETARGET ?= all
|
||||
|
||||
|
||||
@ -43,33 +43,36 @@ build/noise-c/TEST.a: build/libsodium/TEST.a
|
||||
$(QUIET) echo -e "BUILD\t$@"
|
||||
$(QUIET) mkdir -p $(@D)
|
||||
$(QUIET) (cd noise-c && \
|
||||
(git clean -fx ; git submodule foreach --recursive git clean -xf ; true) && \
|
||||
./autogen.sh && \
|
||||
libsodium_CFLAGS=-I$$PWD/../build/libsodium/TEST.a.dir/include/ libsodium_LIBS=$$PWD/../build/libsodium/TEST.a \
|
||||
CC=$(CC) CFLAGS="$(TEST_CFLAGS) -I$(shell ./find_header.sh $(CC) immintrin.h)" ./configure --with-libsodium && \
|
||||
$(MAKE) clean && \
|
||||
$(MAKE)) $(QUIET_OUT)
|
||||
$(MAKE) -C src/protocol) $(QUIET_OUT)
|
||||
$(QUIET) cp noise-c/src/protocol/libnoiseprotocol.a $@
|
||||
$(QUIET) echo -e "BUILT\t$@"
|
||||
build/noise-c/SGX.a: build/libsodium/SGX.a | build/noise-c/TEST.a
|
||||
$(QUIET) echo -e "BUILD\t$@"
|
||||
$(QUIET) mkdir -p $(@D)
|
||||
$(QUIET) (cd noise-c && \
|
||||
(git clean -fx ; git submodule foreach --recursive git clean -xf ; true) && \
|
||||
./autogen.sh && \
|
||||
libsodium_CFLAGS=-I$$PWD/../build/libsodium/SGX.a.dir/include/ libsodium_LIBS=$$PWD/../build/libsodium/SGX.a \
|
||||
CC=$(CC) CFLAGS="$(SGX_CFLAGS) -I$(shell ./find_header.sh $(CC) immintrin.h)" ./configure --with-libsodium && \
|
||||
$(MAKE) clean && \
|
||||
$(MAKE)) $(QUIET_OUT)
|
||||
$(MAKE) -C src/protocol) $(QUIET_OUT)
|
||||
$(QUIET) cp noise-c/src/protocol/libnoiseprotocol.a $@
|
||||
$(QUIET) echo -e "BUILT\t$@"
|
||||
build/noise-c/X86.a: build/libsodium/X86.a | build/noise-c/SGX.a
|
||||
$(QUIET) echo -e "BUILD\t$@"
|
||||
$(QUIET) mkdir -p $(@D)
|
||||
$(QUIET) (cd noise-c && \
|
||||
(git clean -fx ; git submodule foreach --recursive git clean -xf ; true) && \
|
||||
./autogen.sh && \
|
||||
libsodium_CFLAGS=-I$$PWD/../build/libsodium/X86.a.dir/include/ libsodium_LIBS=$$PWD/../build/libsodium/X86.a \
|
||||
CC=$(CC) CFLAGS="$(X86_CFLAGS) -I$(shell ./find_header.sh $(CC) immintrin.h)" ./configure --with-libsodium && \
|
||||
$(MAKE) clean && \
|
||||
$(MAKE)) $(QUIET_OUT)
|
||||
$(MAKE) -C src/protocol) $(QUIET_OUT)
|
||||
$(QUIET) cp noise-c/src/protocol/libnoiseprotocol.a $@
|
||||
$(QUIET) echo -e "BUILT\t$@"
|
||||
|
||||
@ -271,10 +274,11 @@ build/attest.azuresnp: build/initmain/X86.a $(patsubst %,build/%/X86.a,$(AZURESN
|
||||
|
||||
clean:
|
||||
$(QUIET) echo CLEAN
|
||||
$(QUIET) (cd protobuf ; make clean ; git clean -fx ; true) $(QUIET_OUT)
|
||||
$(QUIET) (cd noise-c ; make clean ; git clean -fx ; true) $(QUIET_OUT)
|
||||
$(QUIET) (cd SipHash ; make clean ; git clean -fx ; true) $(QUIET_OUT)
|
||||
$(QUIET) (cd boringssl ; make clean ; git clean -fx ; true) $(QUIET_OUT)
|
||||
$(QUIET) (cd protobuf ; make clean ; true) $(QUIET_OUT)
|
||||
$(QUIET) (cd noise-c ; make clean ; true) $(QUIET_OUT)
|
||||
$(QUIET) (cd SipHash ; make clean ; true) $(QUIET_OUT)
|
||||
$(QUIET) (cd boringssl ; make clean ; true) $(QUIET_OUT)
|
||||
$(QUIET) (git submodule foreach --recursive git clean -xf ; true) $(QUIET_OUT)
|
||||
$(QUIET) rm -vfr build $(QUIET_OUT)
|
||||
$(QUIET) rm -vf .testdepends $(QUIET_OUT)
|
||||
|
||||
|
||||
@ -23,13 +23,23 @@ const NoiseProtocolId client_protocol = {
|
||||
.hybrid_id = 0,
|
||||
};
|
||||
|
||||
const NoiseProtocolId client_protocol_pq = {
|
||||
.prefix_id = NOISE_PREFIX_STANDARD,
|
||||
.pattern_id = NOISE_PATTERN_NK_HFS,
|
||||
.dh_id = NOISE_DH_CURVE25519,
|
||||
.cipher_id = NOISE_CIPHER_CHACHAPOLY,
|
||||
.hash_id = NOISE_HASH_SHA256,
|
||||
.hybrid_id = NOISE_DH_KYBER1024,
|
||||
};
|
||||
|
||||
Client::Client(
|
||||
std::unique_ptr<db::DB::ClientState> cs)
|
||||
std::unique_ptr<db::DB::ClientState> cs, bool pq)
|
||||
: hs_(noise::WrapHandshakeState(nullptr)),
|
||||
tx_(noise::WrapCipherState(nullptr)),
|
||||
rx_(noise::WrapCipherState(nullptr)),
|
||||
id_(id_gen.fetch_add(1)),
|
||||
cs_(std::move(cs)) {
|
||||
cs_(std::move(cs)),
|
||||
pq_(pq) {
|
||||
}
|
||||
|
||||
Client::~Client() {
|
||||
@ -38,7 +48,8 @@ Client::~Client() {
|
||||
error::Error Client::Init(const noise::DHState& dhstate, const e2e::Attestation& attestation) {
|
||||
util::unique_lock lock(mu_);
|
||||
NoiseHandshakeState* hs;
|
||||
if (NOISE_ERROR_NONE != noise_handshakestate_new_by_id(&hs, &client_protocol, NOISE_ROLE_RESPONDER)) {
|
||||
const NoiseProtocolId* protocol = pq_ ? &client_protocol_pq : &client_protocol;
|
||||
if (NOISE_ERROR_NONE != noise_handshakestate_new_by_id(&hs, protocol, NOISE_ROLE_RESPONDER)) {
|
||||
return COUNTED_ERROR(Client_HandshakeState);
|
||||
}
|
||||
auto hs_wrap = noise::WrapHandshakeState(hs);
|
||||
@ -131,7 +142,7 @@ std::pair<Client*, error::Error> ClientManager::NewClient(
|
||||
context::Context* ctx,
|
||||
std::unique_ptr<db::DB::ClientState> cs) {
|
||||
MEASURE_CPU(ctx, cpu_client_hs_start);
|
||||
std::unique_ptr<Client> c(new Client(std::move(cs)));
|
||||
std::unique_ptr<Client> c(new Client(std::move(cs), pq_));
|
||||
auto [dhstate, attestation] = ClientArgs(ctx);
|
||||
error::Error err = c->Init(dhstate, attestation);
|
||||
if (err != error::OK) {
|
||||
|
||||
@ -44,7 +44,7 @@ class Client {
|
||||
|
||||
private:
|
||||
~Client();
|
||||
explicit Client(std::unique_ptr<db::DB::ClientState> cs);
|
||||
Client(std::unique_ptr<db::DB::ClientState> cs, bool pq);
|
||||
error::Error Init(const noise::DHState& dhstate, const e2e::Attestation& attestation) EXCLUDES(mu_);
|
||||
friend class ClientManager;
|
||||
friend std::unique_ptr<Client>::deleter_type;
|
||||
@ -56,11 +56,12 @@ class Client {
|
||||
noise::CipherState rx_ GUARDED_BY(mu_);
|
||||
const size_t id_;
|
||||
std::unique_ptr<db::DB::ClientState> cs_;
|
||||
const bool pq_;
|
||||
};
|
||||
|
||||
class ClientManager {
|
||||
public:
|
||||
ClientManager(noise::DHState dhstate) : dhstate_(std::move(dhstate)) {}
|
||||
ClientManager(noise::DHState dhstate, bool pq) : dhstate_(std::move(dhstate)), pq_(pq) {}
|
||||
error::Error RefreshAttestation(context::Context* ctx, const enclaveconfig::RaftGroupConfig& config) EXCLUDES(mu_);
|
||||
error::Error RotateKeyAndRefreshAttestation(context::Context* ctx, const enclaveconfig::RaftGroupConfig& config) EXCLUDES(mu_);
|
||||
static noise::DHState NewDHState();
|
||||
@ -82,6 +83,7 @@ class ClientManager {
|
||||
noise::DHState dhstate_ GUARDED_BY(mu_);
|
||||
e2e::Attestation attestation_ GUARDED_BY(mu_);
|
||||
std::unordered_map<ClientID, std::unique_ptr<Client>> clients_ GUARDED_BY(mu_);
|
||||
const bool pq_;
|
||||
};
|
||||
|
||||
} // namespace svr2::client
|
||||
|
||||
@ -149,7 +149,7 @@ error::Error Core::Init(context::Context* ctx, const enclaveconfig::EnclaveConfi
|
||||
enclave_config_ = config;
|
||||
}
|
||||
peer_manager_ = std::move(peer_manager);
|
||||
client_manager_ = std::make_unique<client::ClientManager>(std::move(client_dh));
|
||||
client_manager_ = std::make_unique<client::ClientManager>(std::move(client_dh), config.client_pq());
|
||||
clock_.SetLocalTime(initial_timestamp_unix_secs);
|
||||
peer_manager_->SetPeerAttestationTimestamp(ctx, initial_timestamp_unix_secs, raft_config_template_.attestation_timeout());
|
||||
|
||||
|
||||
@ -81,7 +81,8 @@ void Gauge::Clear() {
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
error::Error RecordError(error::Error e) {
|
||||
error::Error RecordError(error::Error e, const char* file, int line) {
|
||||
LOG(VERBOSE) << e << " @ " << file << ":" << line;
|
||||
recorded_errors[e].fetch_add(1);
|
||||
return e;
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ enum Gauges {
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
error::Error RecordError(error::Error);
|
||||
error::Error RecordError(error::Error, const char* file, int line);
|
||||
extern Counter counters[COUNTERS_ARRAY_SIZE];
|
||||
extern Gauge gauges[GAUGES_ARRAY_SIZE];
|
||||
} // namespace internal
|
||||
@ -93,6 +93,6 @@ extern Gauge gauges[GAUGES_ARRAY_SIZE];
|
||||
// COUNTED_ERROR counts an error within metrics, returning that same error.
|
||||
// It's generally used like:
|
||||
// return COUNTED_ERROR(Foo_Bar);
|
||||
#define COUNTED_ERROR(x) ::svr2::metrics::internal::RecordError(error::x)
|
||||
#define COUNTED_ERROR(x) ::svr2::metrics::internal::RecordError(error::x, __FILE__, __LINE__)
|
||||
|
||||
#endif // __SVR2_METRICS_METRICS_H__
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit 9ab8de7db4082d08aea7d5f7bb614ea3e777b09d
|
||||
Subproject commit 68814bedb0dbe893796a585ba9aed7c78360f2da
|
||||
@ -21,7 +21,7 @@
|
||||
|
||||
namespace svr2::noise {
|
||||
|
||||
const size_t HANDSHAKE_INIT_SIZE = 64;
|
||||
const size_t HANDSHAKE_INIT_SIZE = 4096;
|
||||
const size_t HANDSHAKE_HFS_INIT_SIZE = 4096;
|
||||
|
||||
inline uint8_t* StrU8Ptr(std::string* s) {
|
||||
|
||||
@ -55,7 +55,7 @@ static NoiseProtocolId peer_to_peer_protocol = {
|
||||
// have access to hardware-accelerated AES, so we use that.
|
||||
.cipher_id = NOISE_CIPHER_AESGCM,
|
||||
.hash_id = NOISE_HASH_SHA256,
|
||||
.hybrid_id = NOISE_DH_NEWHOPE,
|
||||
.hybrid_id = NOISE_DH_KYBER1024,
|
||||
};
|
||||
|
||||
Peer::Peer(const peerid::PeerID& id, PeerManager* parent)
|
||||
|
||||
@ -6,6 +6,8 @@
|
||||
//TESTDEP metrics
|
||||
//TESTDEP proto
|
||||
//TESTDEP protobuf-lite
|
||||
//TESTDEP env
|
||||
//TESTDEP libsodium
|
||||
#include <gtest/gtest.h>
|
||||
#include "util/hex.h"
|
||||
#include <string>
|
||||
|
||||
@ -15,11 +15,11 @@ enclave_binaries:
|
||||
|
||||
# -count=1 forces this test to run un-cached, since enclave.test may have changed
|
||||
# even though Go code has not, and tests may depend on it.
|
||||
test: build enclave_binaries rustclient
|
||||
test: build enclave_binaries rustclient/target/debug/rustclient
|
||||
go test $(GO_TEST_FLAGS) -count=1 ./...
|
||||
|
||||
rustclient:
|
||||
cd integration/rustclient && cargo build
|
||||
rustclient/target/debug/rustclient:
|
||||
cd rustclient && cargo build
|
||||
|
||||
EDGER8R_FILES=enclave/c/svr2_u.c enclave/c/svr2_u.h enclave/c/svr2_args.h
|
||||
# This $(firstword) trick allows for grouped targets.
|
||||
|
||||
@ -49,37 +49,6 @@ const (
|
||||
enclaveNitro = "nitro"
|
||||
)
|
||||
|
||||
type prefixWriter struct {
|
||||
written bool
|
||||
prefix []byte
|
||||
to io.Writer
|
||||
}
|
||||
|
||||
func (p *prefixWriter) Write(bs []byte) (int, error) {
|
||||
lastStart := 0
|
||||
for i, b := range bs {
|
||||
if !p.written {
|
||||
if n, err := p.to.Write(bs[lastStart:i]); err != nil {
|
||||
return lastStart + n, err
|
||||
}
|
||||
lastStart = i
|
||||
if _, err := p.to.Write(p.prefix); err != nil {
|
||||
return i, err
|
||||
}
|
||||
p.written = true
|
||||
} else if b == '\n' {
|
||||
p.written = false
|
||||
}
|
||||
}
|
||||
if n, err := p.to.Write(bs[lastStart:]); err != nil {
|
||||
return lastStart + n, err
|
||||
}
|
||||
return len(bs), nil
|
||||
}
|
||||
func newPrefixWriter(s string, to io.Writer) io.Writer {
|
||||
return &prefixWriter{to: to, prefix: []byte(s)}
|
||||
}
|
||||
|
||||
func userName(i int) string {
|
||||
return fmt.Sprintf("%032x", i)
|
||||
}
|
||||
@ -92,18 +61,6 @@ func TestIntegration(t *testing.T) {
|
||||
restore(t, testClient(t, u, userName(9999)), pin)
|
||||
}
|
||||
|
||||
func TestRustClient(t *testing.T) {
|
||||
host := fmt.Sprintf("localhost:%v", port(clientType, 1))
|
||||
u := url.URL{Scheme: "ws", Host: host, Path: "v1/enclave"}
|
||||
cmd := exec.Command("./rustclient/target/debug/rustclient", u.String())
|
||||
w := newPrefixWriter("RUSTCLIENT ", os.Stderr)
|
||||
cmd.Stdout = w
|
||||
cmd.Stderr = w
|
||||
if err := cmd.Run(); err != nil {
|
||||
t.Errorf("rustclient: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConcurrentClients(t *testing.T) {
|
||||
host := fmt.Sprintf("localhost:%v", port(clientType, 1))
|
||||
u := url.URL{Scheme: "ws", Host: host, Path: "v1/enclave"}
|
||||
@ -348,7 +305,7 @@ func start(enclaveType string) group {
|
||||
args...)
|
||||
cmd.Env = append(cmd.Env, "AUTH_SECRET="+base64.StdEncoding.EncodeToString([]byte(authSecret)))
|
||||
|
||||
w := newPrefixWriter(fmt.Sprintf("[%d] ", i), os.Stderr)
|
||||
w := servicetest.NewPrefixWriter(fmt.Sprintf("[%d] ", i), os.Stderr)
|
||||
cmd.Stdout = w
|
||||
cmd.Stderr = w
|
||||
|
||||
|
||||
@ -1 +0,0 @@
|
||||
../../../shared/proto/
|
||||
@ -1 +0,0 @@
|
||||
../../../.cargotarget/
|
||||
@ -161,15 +161,19 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.6.1"
|
||||
version = "1.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952"
|
||||
checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.5"
|
||||
version = "1.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "324c74f2155653c90b04f25b2a47a8a631360cb908f92a772695f430c7e31052"
|
||||
checksum = "504bdec147f2cc13c8b57ed9401fd8a147cc66b67ad5cb241394244f2c947549"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@ -329,6 +333,12 @@ dependencies = [
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dunce"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.13.0"
|
||||
@ -348,7 +358,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -440,7 +450,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check 0.9.4",
|
||||
"version_check 0.9.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -464,6 +474,12 @@ dependencies = [
|
||||
"polyval",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
@ -535,9 +551,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.6"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
||||
checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
@ -570,6 +586,15 @@ dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.2"
|
||||
@ -750,9 +775,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.64"
|
||||
version = "0.10.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f"
|
||||
checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"cfg-if 1.0.0",
|
||||
@ -782,9 +807,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.102"
|
||||
version = "0.9.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2"
|
||||
checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@ -865,9 +890,43 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pqcrypto-internals"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9d34bec6abe2283e6de7748b68b292d1ffa2203397e3e71380ff8418a49fb46"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"dunce",
|
||||
"getrandom",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pqcrypto-kyber"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15c00293cf898859d0c771455388054fd69ab712263c73fdc7f287a39b1ba000"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"glob",
|
||||
"libc",
|
||||
"pqcrypto-internals",
|
||||
"pqcrypto-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pqcrypto-traits"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94e851c7654eed9e68d7d27164c454961a616cf8c203d500607ef22c737b51bb"
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
@ -894,7 +953,7 @@ version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e13db3d3fde688c61e2446b4d843bc27a7e8af269a69440c0308021dc92333cc"
|
||||
dependencies = [
|
||||
"bytes 1.6.1",
|
||||
"bytes 1.7.1",
|
||||
"prost-derive",
|
||||
]
|
||||
|
||||
@ -904,7 +963,7 @@ version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5bb182580f71dd070f88d01ce3de9f4da5021db7115d2e1c3605a754153b77c1"
|
||||
dependencies = [
|
||||
"bytes 1.6.1",
|
||||
"bytes 1.7.1",
|
||||
"heck",
|
||||
"itertools",
|
||||
"log 0.4.22",
|
||||
@ -1103,9 +1162,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.5"
|
||||
version = "1.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
|
||||
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@ -1173,7 +1232,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1188,7 +1247,7 @@ version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1298,6 +1357,8 @@ dependencies = [
|
||||
"blake2",
|
||||
"chacha20poly1305",
|
||||
"curve25519-dalek",
|
||||
"pqcrypto-kyber",
|
||||
"pqcrypto-traits",
|
||||
"rand_core 0.6.4",
|
||||
"rustc_version 0.4.0",
|
||||
"sha2",
|
||||
@ -1312,9 +1373,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.71"
|
||||
version = "2.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462"
|
||||
checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1323,14 +1384,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.10.1"
|
||||
version = "3.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
|
||||
checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"fastrand",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1528,9 +1590,9 @@ checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
@ -1628,6 +1690,15 @@ dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
@ -1702,6 +1773,27 @@ dependencies = [
|
||||
"winapi-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.8.1"
|
||||
@ -6,7 +6,7 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
snow = "0.9.6"
|
||||
snow = { version = "0.9.6", features = ["hfs", "pqclean_kyber1024"] }
|
||||
websocket = "0.27.1"
|
||||
prost = "0.13.1"
|
||||
simple-error = "0.3.1"
|
||||
@ -1,3 +1,6 @@
|
||||
// Copyright 2024 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
fn main() {
|
||||
let protos = [
|
||||
"proto/msgs.proto",
|
||||
1
host/rustclient/proto
Symbolic link
1
host/rustclient/proto
Symbolic link
@ -0,0 +1 @@
|
||||
../../shared/proto/
|
||||
124
host/rustclient/rustclient_test.go
Normal file
124
host/rustclient/rustclient_test.go
Normal file
@ -0,0 +1,124 @@
|
||||
// Copyright 2024 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
package rustclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/alicebob/miniredis/v2"
|
||||
"github.com/signalapp/svr2/servicetest"
|
||||
"google.golang.org/protobuf/encoding/prototext"
|
||||
|
||||
pb "github.com/signalapp/svr2/proto"
|
||||
)
|
||||
|
||||
var (
|
||||
validConfig = pb.InitConfig{
|
||||
EnclaveConfig: &pb.EnclaveConfig{
|
||||
Raft: &pb.RaftConfig{
|
||||
ElectionTicks: 30,
|
||||
HeartbeatTicks: 15,
|
||||
ReplicationChunkBytes: 1 << 20,
|
||||
ReplicaVotingTimeoutTicks: 120,
|
||||
ReplicaMembershipTimeoutTicks: 240,
|
||||
LogMaxBytes: 10 << 20,
|
||||
},
|
||||
E2ETxnTimeoutTicks: 30,
|
||||
ClientPq: true,
|
||||
},
|
||||
GroupConfig: &pb.RaftGroupConfig{
|
||||
DbVersion: pb.DatabaseVersion_DATABASE_VERSION_SVR2,
|
||||
MinVotingReplicas: 1,
|
||||
MaxVotingReplicas: 1,
|
||||
AttestationTimeout: 3600,
|
||||
Simulated: true,
|
||||
},
|
||||
}
|
||||
hostPath = "../main"
|
||||
sgxPath = "../../enclave/build/enclave.test"
|
||||
clientPath = "target/debug/rustclient"
|
||||
authSecret = "123456"
|
||||
)
|
||||
|
||||
func hostConfig(redisAddr string) string {
|
||||
return fmt.Sprintf(`
|
||||
peerAddr: localhost:9990
|
||||
clientListenAddr: localhost:9991
|
||||
controlListenAddr: localhost:9992
|
||||
raft:
|
||||
tickDuration: 250ms
|
||||
redis:
|
||||
addrs: [%s]`, redisAddr)
|
||||
}
|
||||
|
||||
func TestRustClient(t *testing.T) {
|
||||
dir, err := os.MkdirTemp("", "rustclient")
|
||||
if err != nil {
|
||||
t.Fatalf("mkdir: %v", err)
|
||||
}
|
||||
t.Logf("using dir %v", dir)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
redis, err := miniredis.Run()
|
||||
if err != nil {
|
||||
t.Fatalf("miniredis: %v", err)
|
||||
}
|
||||
hConfig := hostConfig(redis.Addr())
|
||||
|
||||
eConfig, err := prototext.Marshal(&validConfig)
|
||||
if err != nil {
|
||||
t.Fatalf("proto marshal: %v", err)
|
||||
}
|
||||
|
||||
if err := os.WriteFile(filepath.Join(dir, "hconfig"), []byte(hConfig), 0600); err != nil {
|
||||
t.Fatalf("write hconfig: %v", err)
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(dir, "econfig"), eConfig, 0600); err != nil {
|
||||
t.Fatalf("write econfig: %v", err)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
hostCmd := exec.CommandContext(
|
||||
ctx,
|
||||
hostPath,
|
||||
"-hconfig_path", filepath.Join(dir, "hconfig"),
|
||||
"-econfig_path", filepath.Join(dir, "econfig"),
|
||||
"-enclave_type", "sgx",
|
||||
"-sgx_path", sgxPath)
|
||||
hostCmd.Env = append(hostCmd.Env, "AUTH_SECRET="+base64.StdEncoding.EncodeToString([]byte(authSecret)))
|
||||
hostCmd.Stdout = servicetest.NewPrefixWriter("HOST_OUT: ", os.Stderr)
|
||||
hostCmd.Stderr = servicetest.NewPrefixWriter("HOST_ERR: ", os.Stderr)
|
||||
|
||||
defer time.Sleep(time.Second) // allow logs to make it out.
|
||||
t.Logf("Starting...")
|
||||
if err := hostCmd.Start(); err != nil {
|
||||
t.Fatalf("starting: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("Waiting for healthy")
|
||||
if err := servicetest.WaitFor200(time.Minute, "http://localhost:9992/health/ready"); err != nil {
|
||||
t.Fatalf("wait for 200: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("Running test")
|
||||
u := url.URL{Scheme: "ws", Host: "localhost:9991", Path: "v1/enclave"}
|
||||
clientCmd := exec.CommandContext(
|
||||
ctx,
|
||||
clientPath,
|
||||
u.String())
|
||||
clientCmd.Stdout = servicetest.NewPrefixWriter("CLIENT_OUT: ", os.Stderr)
|
||||
clientCmd.Stderr = servicetest.NewPrefixWriter("CLIENT_ERR: ", os.Stderr)
|
||||
if err := clientCmd.Run(); err != nil {
|
||||
t.Fatalf("client error: %v", err)
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,6 @@
|
||||
// Copyright 2024 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
use hmac::Mac;
|
||||
use websocket::header::{Authorization, Basic, Headers};
|
||||
use prost::Message;
|
||||
@ -25,7 +28,7 @@ pub mod svr2 {
|
||||
|
||||
type HmacSha256 = hmac::Hmac<sha2::Sha256>;
|
||||
|
||||
static PATTERN: &'static str = "Noise_NK_25519_ChaChaPoly_SHA256";
|
||||
static PATTERN: &'static str = "Noise_NKhfs_25519+Kyber1024_ChaChaPoly_SHA256";
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
@ -77,9 +80,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Send handshake start");
|
||||
client.send_message(&websocket::Message::binary(&buf[..len]))?;
|
||||
|
||||
println!("Recv handshake finish");
|
||||
println!("Recv handshake start");
|
||||
let msg2 = client.recv_message()?;
|
||||
let bin2 = if let websocket::OwnedMessage::Binary(b) = msg2 {
|
||||
println!("Received!");
|
||||
b
|
||||
} else {
|
||||
bail!("received message not binary");
|
||||
1
host/rustclient/target
Symbolic link
1
host/rustclient/target
Symbolic link
@ -0,0 +1 @@
|
||||
../../.cargotarget/
|
||||
@ -79,3 +79,34 @@ func WaitFor200(timeout time.Duration, url string) error {
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
type PrefixWriter struct {
|
||||
written bool
|
||||
prefix []byte
|
||||
to io.Writer
|
||||
}
|
||||
|
||||
func (p *PrefixWriter) Write(bs []byte) (int, error) {
|
||||
lastStart := 0
|
||||
for i, b := range bs {
|
||||
if !p.written {
|
||||
if n, err := p.to.Write(bs[lastStart:i]); err != nil {
|
||||
return lastStart + n, err
|
||||
}
|
||||
lastStart = i
|
||||
if _, err := p.to.Write(p.prefix); err != nil {
|
||||
return i, err
|
||||
}
|
||||
p.written = true
|
||||
} else if b == '\n' {
|
||||
p.written = false
|
||||
}
|
||||
}
|
||||
if n, err := p.to.Write(bs[lastStart:]); err != nil {
|
||||
return lastStart + n, err
|
||||
}
|
||||
return len(bs), nil
|
||||
}
|
||||
func NewPrefixWriter(s string, to io.Writer) io.Writer {
|
||||
return &PrefixWriter{to: to, prefix: []byte(s)}
|
||||
}
|
||||
|
||||
@ -48,6 +48,8 @@ message EnclaveConfig {
|
||||
uint32 e2e_txn_timeout_ticks = 2;
|
||||
// Every N ticks, send our local timestamp to our peers.
|
||||
uint32 send_timestamp_ticks = 5;
|
||||
// If true, use HFS for client/server PQ protection.
|
||||
bool client_pq = 6;
|
||||
}
|
||||
|
||||
// RaftGroupConfig is a configuration shared by members of a Raft group.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user