Use Kyber1024 for HFS in Noise.

Co-authored-by: Chris Eager <79161849+eager-signal@users.noreply.github.com>
This commit is contained in:
gram-signal 2025-03-19 12:35:45 -07:00 committed by GitHub
parent cbb66d99df
commit a009895eb8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 80 additions and 33 deletions

View File

@ -18,7 +18,7 @@ jobs:
- name: Checkout main project
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
submodules: recursive
path: cdsi
- name: Set up JDK 21

View File

@ -15,7 +15,7 @@ jobs:
- name: Checkout main project
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
submodules: recursive
path: cdsi
- name: Docker cache
@ -40,7 +40,7 @@ jobs:
- name: Checkout main project
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
submodules: recursive
path: cdsi
- name: Docker cache
@ -65,7 +65,7 @@ jobs:
- name: Checkout main project
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
submodules: recursive
path: cdsi
- name: Set up JDK 21
@ -106,7 +106,7 @@ jobs:
- name: Checkout main project
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: true
submodules: recursive
path: cdsi
- name: Set up JDK 21
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0

7
.gitmodules vendored
View File

@ -1,6 +1,9 @@
[submodule "c/sgx/oram/src/SipHash"]
path = c/SipHash
url = https://github.com/veorq/SipHash
[submodule "c/sgx/enclave/noise-c"]
[submodule "c/noise-c"]
path = c/noise-c
url = https://github.com/rweather/noise-c.git
url = https://github.com/signalapp/noise-c.git
[submodule "c/libsodium"]
path = c/libsodium
url = https://github.com/jedisct1/libsodium

View File

@ -13,7 +13,8 @@ Building
```
git submodule init
git submodule update
git submodule update --recursive --init || true
git submodule update --recursive || true
mvn verify
```

View File

@ -42,15 +42,33 @@ proto: cdsi.h cdsi.c
enclave: proto
libnoise.a:
LIBSODIUM_UNDEFS = \
-UHAVE_MMAP \
-UHAVE_MLOCK \
-UHAVE_MADVISE \
-UHAVE_MPROTECT \
-UHAVE_RAISE \
##LIBSODIUM_UNDEFS
libsodium.a:
rm -rf $$(pwd)/libsodium/.build && mkdir -p $$(pwd)/libsodium/.build
(cd libsodium && (git clean -fxd || true) && ./configure \
CFLAGS="$(TRUSTED_CFLAGS) $(LIBSODIUM_UNDEFS)" \
CXXFLAGS="$(TRUSTED_CXXFLAGS) $(LIBSODIUM_UNDEFS)" \
CC=$(CC) CXX=$(CXX) --prefix=$$(pwd)/.build && $(MAKE) clean && $(MAKE) install)
cp -fv $$(pwd)/libsodium/.build/lib/libsodium.a $@
libnoise.a: libsodium.a
mkdir -p $$(dirname $@)
# Noise depends on the "immintrin" header which is not found in the pared-down
# version of libc we use, and which it could otherwise not find with -nostdinc.
(cd noise-c && \
(git clean -fxd ; git submodule foreach --recursive git clean -xfd ; true) && \
./autogen.sh && \
libsodium_CFLAGS=-I$$(pwd)/.libsodium/include/ libsodium_LIBS=libsodium.a \
CC=$(TRUSTED_CC) CFLAGS="$(TRUSTED_CFLAGS) -I$(shell ./find_header.sh $(CC) immintrin.h)" ./configure && \
$(MAKE) -j)
cp -v noise-c/src/protocol/libnoiseprotocol.a libnoise.a
cp -vf noise-c/src/protocol/libnoiseprotocol.a libnoise.a
libsip.a: SipHash/halfsiphash.c
$(TRUSTED_CC) $(TRUSTED_CFLAGS) -o SipHash/halfsiphash.o -c SipHash/halfsiphash.c
@ -226,6 +244,7 @@ TESTS=\
tests: $(patsubst %,%.out,$(TESTS)) enclave.test.out constant_time_check.test
@echo ALL TESTS SUCCEEDED
valgrinds: $(patsubst %,%.valgrind,$(TESTS))
public.pem:
@ -261,11 +280,12 @@ clean:
enclave.test.out \
proto/cdsi.c \
proto/cdsi.h \
libsodium/.build \
##
for dir in $(SUBDIRS); do make -C $$dir -f ../Makefile.subdirs clean; done
(cd noise-c && \
($(MAKE) clean || true) && \
(git clean -fx || true)) >/dev/null
(git clean -fx ; git submodule foreach --recursive git clean -xfd ; true)) >/dev/null
@echo CLEAN
docker_%:

View File

@ -387,12 +387,12 @@ int enclave_new_client(
RETURN_IF_ERROR(check_init_complete());
client_t *c;
RETURN_IF_ERROR(MALLOCZ(c));
TEST_LOG("noise_handshakestate_new_by_name '%s'", NOISE_PROTOCOL_DEFINITION);
TEST_LOG("noise_handshakestate_new_by_id");
error_t err = err_SUCCESS;
GOTO_IF_ERROR(err = noise_errort(
err_NOISE__HANDSHAKESTATE__NEW__,
noise_handshakestate_new_by_name(
&c->handshake, NOISE_PROTOCOL_DEFINITION, NOISE_ROLE_RESPONDER)),
noise_handshakestate_new_by_id(
&c->handshake, &cdsi_client_protocol_id, NOISE_ROLE_RESPONDER)),
free_client);
NoiseDHState *local_keypair = noise_handshakestate_get_local_keypair_dh(c->handshake);
@ -837,7 +837,7 @@ int enclave_handshake(
GOTO_IF_ERROR(err = noise_errort(err_NOISE__HANDSHAKESTATE__READ__, noise_handshakestate_read_message(c->handshake, &buf_in, NULL)), client_unlock);
// Generate the handshake response.
unsigned char handshake_msg[64];
unsigned char handshake_msg[NOISE_HANDSHAKEWRITE_SIZE];
NoiseBuffer buf_out;
noise_buffer_set_output(buf_out, handshake_msg, sizeof(handshake_msg));
TEST_LOG("noise_handshakestate_write_message");

1
c/libsodium Submodule

@ -0,0 +1 @@
Subproject commit fb4533b0a941b3a5b1db5687d1b008a5853d1f29

@ -1 +1 @@
Subproject commit 9379e580a14c0374a57d826a49ba53b7440c80bc
Subproject commit 68814bedb0dbe893796a585ba9aed7c78360f2da

View File

@ -4,6 +4,23 @@
#include <noise/protocol/constants.h>
#include <string.h>
const NoiseProtocolId cdsi_client_protocol_id = {
.prefix_id = NOISE_PREFIX_STANDARD,
#ifdef NO_NOISE_HFS
.pattern_id = NOISE_PATTERN_NK,
#else
.pattern_id = NOISE_PATTERN_NK_HFS,
#endif
.dh_id = NOISE_DH_CURVE25519,
.cipher_id = NOISE_CIPHER_CHACHAPOLY,
.hash_id = NOISE_HASH_SHA256,
#ifdef NO_NOISE_HFS
.hybrid_id = 0,
#else
.hybrid_id = NOISE_DH_KYBER1024,
#endif
};
error_t noise_encrypt_message(
NoiseCipherState* tx,
const unsigned char* plaintext_data,
@ -76,7 +93,7 @@ error_t noise_pubkey_from_privkey(
unsigned char pubkey[NOISE_KEY_SIZE]) {
NoiseDHState* state;
error_t err = err_SUCCESS;
RETURN_IF_ERROR(noise_errort(err_NOISE__DHSTATE__NEW__, noise_dhstate_new_by_name(&state, NOISE_DH_TYPE)));
RETURN_IF_ERROR(noise_errort(err_NOISE__DHSTATE__NEW__, noise_dhstate_new_by_id(&state, cdsi_client_protocol_id.dh_id)));
GOTO_IF_ERROR(err = noise_errort(err_NOISE__DHSTATE__SET_KEYPAIR_PRIVATE__, noise_dhstate_set_keypair_private(state, privkey, NOISE_KEY_SIZE)), free_state);
GOTO_IF_ERROR(err = noise_errort(err_NOISE__DHSTATE__GET_PUBLIC_KEY__, noise_dhstate_get_public_key(state, pubkey, NOISE_KEY_SIZE)), free_state);

View File

@ -4,18 +4,17 @@
#define _CDSI_NOISE_H
#include <noise/protocol.h>
#define NOISE_PROTOCOL_TYPE "NK"
#define NOISE_DH_TYPE "25519"
#define NOISE_TYPE_SUFFIX NOISE_DH_TYPE "_ChaChaPoly_SHA256"
#define NOISE_PROTOCOL_DEFINITION "Noise_" NOISE_PROTOCOL_TYPE "_" NOISE_TYPE_SUFFIX
#define NOISE_MAX_OVERHEAD 64
#define NOISE_KEY_SIZE 32
#define NOISE_MAX_PACKET_SIZE NOISE_MAX_PAYLOAD_LEN
#define NOISE_MAC_SIZE 16
#define NOISE_MAX_DATA_SIZE (NOISE_MAX_PACKET_SIZE - NOISE_MAC_SIZE)
#define NOISE_HANDSHAKEWRITE_SIZE 1632
#include "util/util.h"
extern const NoiseProtocolId cdsi_client_protocol_id;
#define NOISE_ERROR_BASE NOISE_ID('E', 0)
error_t noise_errort(error_t space, int noise_error);

View File

@ -24,10 +24,13 @@
static void test_noise_message_encrypt_decrypt() {
NoiseHandshakeState* ah;
NoiseHandshakeState* bh;
NOISE_ASSERT(noise_handshakestate_new_by_name(
&ah, "Noise_NN_25519_ChaChaPoly_SHA256", NOISE_ROLE_INITIATOR));
NOISE_ASSERT(noise_handshakestate_new_by_name(
&bh, "Noise_NN_25519_ChaChaPoly_SHA256", NOISE_ROLE_RESPONDER));
NoiseProtocolId id;
memcpy(&id, &cdsi_client_protocol_id, sizeof(id));
id.pattern_id = NOISE_PATTERN_NN_HFS;
NOISE_ASSERT(noise_handshakestate_new_by_id(
&ah, &id, NOISE_ROLE_INITIATOR));
NOISE_ASSERT(noise_handshakestate_new_by_id(
&bh, &id, NOISE_ROLE_RESPONDER));
NOISE_ASSERT(noise_handshakestate_start(ah));
NOISE_ASSERT(noise_handshakestate_start(bh));
@ -36,7 +39,6 @@ static void test_noise_message_encrypt_decrypt() {
NoiseCipherState* brx;
NoiseCipherState* btx;
uint8_t* bufbuf = calloc(1, BUFSIZE);
NoiseBuffer buf;
noise_buffer_set_output(buf, bufbuf, BUFSIZE);
NOISE_ASSERT(noise_handshakestate_write_message(ah, &buf, NULL));
@ -70,5 +72,6 @@ static void test_noise_message_encrypt_decrypt() {
}
int main(int argc, char** argv) {
printf("Running\n");
test_noise_message_encrypt_decrypt();
}

View File

@ -110,7 +110,7 @@ exit:
int perform_handshake(enclave_client_state *ecs, bool simulate, uint8_t pubkey[NOISE_KEY_SIZE])
{
int err, retval, result;
RETURN_IF_ERROR(noise_errort(err_NOISE__HANDSHAKESTATE__NEW__, noise_handshakestate_new_by_name(&ecs->handshake, NOISE_PROTOCOL_DEFINITION, NOISE_ROLE_INITIATOR)));
RETURN_IF_ERROR(noise_errort(err_NOISE__HANDSHAKESTATE__NEW__, noise_handshakestate_new_by_id(&ecs->handshake, &cdsi_client_protocol_id, NOISE_ROLE_INITIATOR)));
NoiseDHState *dhstate = noise_handshakestate_get_remote_public_key_dh(ecs->handshake);
RETURN_IF_ERROR(noise_errort(err_NOISE__DHSTATE__SET_PUBLIC_KEY__, noise_dhstate_set_public_key(dhstate, pubkey, NOISE_KEY_SIZE)));
RETURN_IF_ERROR(noise_errort(err_NOISE__HANDSHAKESTATE__START__, noise_handshakestate_start(ecs->handshake)));
@ -120,12 +120,12 @@ int perform_handshake(enclave_client_state *ecs, bool simulate, uint8_t pubkey[N
return err_HOST__HANDSHAKE__INVALID_STATE;
}
NoiseBuffer mbuf;
uint8_t message[64];
uint8_t message[4096];
noise_buffer_set_output(mbuf, message, sizeof(message));
RETURN_IF_ERROR(noise_errort(err_NOISE__HANDSHAKESTATE__WRITE__, noise_handshakestate_write_message(ecs->handshake, &mbuf, NULL)));
size_t in_size = mbuf.size;
CHECK(in_size == 48);
CHECK(in_size == NOISE_HANDSHAKEWRITE_SIZE);
uint8_t *in = message;
uint8_t out[8192];
size_t actual_out_size = 0;

View File

@ -169,7 +169,7 @@ int call_ratelimit(enclave_client_state *ecs, client_request req)
int noise_err = noise_cipherstate_decrypt(ecs->recv, &buf_out);
if (NOISE_ERROR_NONE != noise_err)
{
noise_perror(NOISE_PROTOCOL_DEFINITION, noise_err);
noise_perror("noise_cipherstate_decrypt", noise_err);
err = err_HOST__RATELIMIT__DECRYPT;
}
@ -264,7 +264,7 @@ int run(enclave_client_state *ecs, size_t num_triples, e164_pni_aci_triple *trip
int noise_err = noise_cipherstate_decrypt(ecs->recv, &buf_out);
if (NOISE_ERROR_NONE != noise_err)
{
noise_perror(NOISE_PROTOCOL_DEFINITION, noise_err);
noise_perror("noise_cipherstate_decrypt", noise_err);
return err_HOST__RUN__DECRYPT;
}

View File

@ -418,7 +418,9 @@
</goals>
<configuration>
<executable>make</executable>
<commandlineArgs>ENCLAVE_ID=test CONFIG=cds-test.conf RESOURCES_DIR=${project.build.testOutputDirectory}/org/signal/cdsi/enclave ADDITIONAL_CFLAGS="-DINSECURE" -C c ${make.docker.prefix}install</commandlineArgs>
<!-- Our Java-side Noise client library doesn't support HFS+Kyber1024,
so we have to pass in -DNO_NOISE_HFS. -->
<commandlineArgs>ENCLAVE_ID=test CONFIG=cds-test.conf RESOURCES_DIR=${project.build.testOutputDirectory}/org/signal/cdsi/enclave ADDITIONAL_CFLAGS="-DINSECURE -DNO_NOISE_HFS" -C c ${make.docker.prefix}install</commandlineArgs>
</configuration>
</execution>
</executions>

View File

@ -335,7 +335,8 @@ public class Enclave implements AutoCloseable {
}
CompletableFuture<ByteBuffer> clientHandshake(final EnclaveClient client, final ByteBuffer in) {
final ByteBuffer out = ByteBuffer.allocateDirect(1024);
// see noise.h: NOISE_HANDSHAKEWRITE_SIZE
final ByteBuffer out = ByteBuffer.allocateDirect(1632);
return supplyAsync(HANDSHAKE_TIMER_NAME, () -> {
try {