]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
CGO: Split modes into forward and backward variants.
authorNick Mathewson <nickm@torproject.org>
Wed, 23 Apr 2025 15:19:43 +0000 (11:19 -0400)
committerNick Mathewson <nickm@torproject.org>
Wed, 21 May 2025 13:43:51 +0000 (09:43 -0400)
I'll need this for getting tags right wrt torspec!328.

src/core/crypto/relay_crypto_cgo.c
src/core/crypto/relay_crypto_cgo.h
src/test/test_crypto_cgo.c

index 5f54d4e157db3012a1370fc2e5b3e913c0a63641..5ff8346b9fe4bad98c1731d5e823a9382d6a9e13 100644 (file)
@@ -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!
index abd0caf6fece1ab795ccdaec6f6ba50fbd40c331..fd3f89288fd4bd53468138c2b284aa604935ccee 100644 (file)
 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
 
index 44bb88fe277f02d6303bdf02509b85f308830e62..403dcaa98bdc78793a405de152853496822a328b 100644 (file)
@@ -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);
     }