From: Nick Mathewson Date: Wed, 23 Apr 2025 15:19:43 +0000 (-0400) Subject: CGO: Split modes into forward and backward variants. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f6fc4f0e8df14733fa137134bd6063438098904;p=thirdparty%2Ftor.git CGO: Split modes into forward and backward variants. I'll need this for getting tags right wrt torspec!328. --- diff --git a/src/core/crypto/relay_crypto_cgo.c b/src/core/crypto/relay_crypto_cgo.c index 5f54d4e157..5ff8346b9f 100644 --- a/src/core/crypto/relay_crypto_cgo.c +++ b/src/core/crypto/relay_crypto_cgo.c @@ -363,7 +363,8 @@ cgo_crypt_new(cgo_mode_t mode, int aesbits, const uint8_t *keys, size_t keylen) const uint8_t *end_of_keys = keys + keylen; // Relays encrypt; clients decrypt. // Don't reverse this: UIV+ is only non-malleable for _encryption_. - bool encrypt = (mode == CGO_MODE_RELAY); + bool encrypt = (mode == CGO_MODE_RELAY_BACKWARD || + mode == CGO_MODE_RELAY_FORWARD); int r; cgo_crypt_t *cgo = tor_malloc_zero(sizeof(cgo_crypt_t)); @@ -397,7 +398,8 @@ cgo_crypt_free_(cgo_crypt_t *cgo) static void cgo_crypt_update(cgo_crypt_t *cgo, cgo_mode_t mode) { - bool encrypt = (mode == CGO_MODE_RELAY); + bool encrypt = (mode == CGO_MODE_RELAY_BACKWARD || + mode == CGO_MODE_RELAY_FORWARD); cgo_uiv_update(&cgo->uiv, cgo->aes_bytes * 8, encrypt, cgo->nonce); } @@ -426,7 +428,7 @@ cgo_crypt_relay_forward(cgo_crypt_t *cgo, cell_t *cell, cgo_uiv_encrypt(&cgo->uiv, h, cell->payload); memcpy(cgo->tprime, cell->payload, CGO_TAG_LEN); if (tor_memeq(cell->payload, cgo->nonce, CGO_TAG_LEN)) { - cgo_crypt_update(cgo, CGO_MODE_RELAY); + cgo_crypt_update(cgo, CGO_MODE_RELAY_FORWARD); // XXXX: Here and in Arti, we've used tprime as the value // of our tag, but the proposal says to use T. We should // fix that, unless the CGO implementors say it's better! @@ -483,7 +485,7 @@ cgo_crypt_relay_originate(cgo_crypt_t *cgo, cell_t *cell, // fix that, unless the CGO implementors say it's better! *tag_out = cgo->tprime; } - cgo_crypt_update(cgo, CGO_MODE_RELAY); + cgo_crypt_update(cgo, CGO_MODE_RELAY_BACKWARD); } /** @@ -523,7 +525,7 @@ cgo_crypt_client_originate(cgo_crypt_t *cgo, cell_t *cell, { memcpy(cell->payload, cgo->nonce, CGO_TAG_LEN); cgo_crypt_client_forward(cgo, cell); - cgo_crypt_update(cgo, CGO_MODE_CLIENT); + cgo_crypt_update(cgo, CGO_MODE_CLIENT_FORWARD); // XXXX: Here and elsewhere, we've used tprime as the value // of our tag, but the proposal says to use T. We should // fix that, unless the CGO implementors say it's better! @@ -559,7 +561,7 @@ cgo_crypt_client_backward(cgo_crypt_t *cgo, cell_t *cell, memcpy(cgo->tprime, t_orig, CGO_TAG_LEN); if (tor_memeq(cell->payload, cgo->nonce, CGO_TAG_LEN)) { memcpy(cgo->nonce, t_orig, CGO_TAG_LEN); - cgo_crypt_update(cgo, CGO_MODE_CLIENT); + cgo_crypt_update(cgo, CGO_MODE_CLIENT_BACKWARD); // XXXX: Here and elsewhere, we've used tprime as the value // of our tag, but the proposal says to use T. We should // fix that, unless the CGO implementors say it's better! diff --git a/src/core/crypto/relay_crypto_cgo.h b/src/core/crypto/relay_crypto_cgo.h index abd0caf6fe..fd3f89288f 100644 --- a/src/core/crypto/relay_crypto_cgo.h +++ b/src/core/crypto/relay_crypto_cgo.h @@ -23,8 +23,10 @@ typedef struct cgo_crypt_t cgo_crypt_t; typedef enum { - CGO_MODE_CLIENT, - CGO_MODE_RELAY, + CGO_MODE_CLIENT_FORWARD, + CGO_MODE_CLIENT_BACKWARD, + CGO_MODE_RELAY_FORWARD, + CGO_MODE_RELAY_BACKWARD, } cgo_mode_t; /** @@ -204,6 +206,8 @@ struct cgo_crypt_t { uint8_t nonce[CGO_TAG_LEN]; uint8_t tprime[CGO_TAG_LEN]; uint8_t aes_bytes; + + uint8_t last_tag_relay_fwd[CGO_TAG_LEN]; }; #endif diff --git a/src/test/test_crypto_cgo.c b/src/test/test_crypto_cgo.c index 44bb88fe27..403dcaa98b 100644 --- a/src/test/test_crypto_cgo.c +++ b/src/test/test_crypto_cgo.c @@ -325,9 +325,9 @@ test_crypto_cgo_fwd(void *arg) tt_uint_op(klen, OP_LE, sizeof(key_material[0])); crypto_rand((char*)&key_material, sizeof(key_material)); for (int i = 0; i < N_HOPS; ++i) { - client[i] = cgo_crypt_new(CGO_MODE_CLIENT, + client[i] = cgo_crypt_new(CGO_MODE_CLIENT_FORWARD, aesbits, key_material[i], klen); - relays[i] = cgo_crypt_new(CGO_MODE_RELAY, + relays[i] = cgo_crypt_new(CGO_MODE_RELAY_FORWARD, aesbits, key_material[i], klen); } for (int trial = 0; trial < 64; ++trial) { @@ -406,9 +406,9 @@ test_crypto_cgo_rev(void *arg) tt_uint_op(klen, OP_LE, sizeof(key_material[0])); crypto_rand((char*)&key_material, sizeof(key_material)); for (int i = 0; i < N_HOPS; ++i) { - client[i] = cgo_crypt_new(CGO_MODE_CLIENT, + client[i] = cgo_crypt_new(CGO_MODE_CLIENT_BACKWARD, aesbits, key_material[i], klen); - relays[i] = cgo_crypt_new(CGO_MODE_RELAY, + relays[i] = cgo_crypt_new(CGO_MODE_RELAY_BACKWARD, aesbits, key_material[i], klen); } for (int trial = 0; trial < 64; ++trial) { @@ -477,7 +477,9 @@ test_crypto_cgo_relay_testvec(void *arg) cell_t expect_cell; tt_int_op(sizeof(keys), OP_EQ, cgo_key_material_len(aesbits)); UNHEX2(keys, tv->state_in.keys, tv->state_in.nonce); - cgo = cgo_crypt_new(CGO_MODE_RELAY, aesbits, keys, sizeof(keys)); + cgo_mode_t mode = + tv->inbound ? CGO_MODE_RELAY_BACKWARD : CGO_MODE_RELAY_FORWARD; + cgo = cgo_crypt_new(mode, aesbits, keys, sizeof(keys)); tt_assert(cgo); UNHEX(cgo->tprime, tv->state_in.tprime); memset(&cell, 0, sizeof(cell)); @@ -528,7 +530,7 @@ test_crypto_cgo_relay_originate_testvec(void *arg) cell_t expect_cell; tt_int_op(sizeof(keys), OP_EQ, cgo_key_material_len(aesbits)); UNHEX2(keys, tv->state_in.keys, tv->state_in.nonce); - cgo = cgo_crypt_new(CGO_MODE_RELAY, aesbits, keys, sizeof(keys)); + cgo = cgo_crypt_new(CGO_MODE_RELAY_BACKWARD, aesbits, keys, sizeof(keys)); tt_assert(cgo); UNHEX(cgo->tprime, tv->state_in.tprime); memset(&cell, 0, sizeof(cell)); @@ -577,7 +579,8 @@ test_crypto_cgo_client_originate_testvec(void *arg) for (int i = 0; i < 3; ++i) { tt_int_op(sizeof(keys), OP_EQ, cgo_key_material_len(aesbits)); UNHEX2(keys, tv->state_in[i].keys, tv->state_in[i].nonce); - cgo[i] = cgo_crypt_new(CGO_MODE_CLIENT, aesbits, keys, sizeof(keys)); + cgo[i] = cgo_crypt_new(CGO_MODE_CLIENT_FORWARD, + aesbits, keys, sizeof(keys)); tt_assert(cgo[i]); UNHEX(cgo[i]->tprime, tv->state_in[i].tprime); }