Tor 0.4.9.2-alpha-dev
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
relay_crypto_cgo.c
Go to the documentation of this file.
1/* Copyright (c) 2001 Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2025, The Tor Project, Inc. */
5/* See LICENSE for licensing information */
6
7/**
8 * \file relay_crypto_cgo.c
9 * \brief Implementation for counter galois onion encryption.
10 **/
11
12#define RELAY_CRYPTO_CGO_PRIVATE
13#define USE_AES_RAW
14
15#include "orconfig.h"
16#include "core/or/or.h"
17#include "lib/crypt_ops/aes.h"
18#include "ext/polyval/polyval.h"
20#include "lib/log/util_bug.h"
21#include "lib/arch/bytes.h"
22#include "ext/polyval/polyval.h"
24#include "core/or/cell_st.h"
25
26#if 0
27// XXXX debugging.
29#include <stdio.h>
30#endif
31
32#include <string.h>
33
34static int
35cgo_et_keylen(int aesbits)
36{
37 return (aesbits / 8) + POLYVAL_KEY_LEN;
38}
39
40/** Initialize an instance of the tweakable block cipher,
41 * using an 'aesbits'-bit AES key.
42 *
43 * The total key material used from 'key' will be
44 * (aesbits / 8) + 16.
45 *
46 * This will be initialized for encryption or decryption depending
47 * on the value of 'encrypt'
48 */
49STATIC int
50cgo_et_init(cgo_et_t *et, int aesbits, bool encrypt,
51 const uint8_t *key)
52{
53 size_t aes_key_bytes = aesbits / 8;
54 et->kb = aes_raw_new(key, aesbits, encrypt);
55 if (et->kb == NULL)
56 return -1;
57 polyvalx_init(&et->ku, key + aes_key_bytes);
58 return 0;
59}
60/** Replace the key on an existing, already initialized cgo_et_t.
61 *
62 * Does fewer allocations than a clear+init. */
63STATIC void
64cgo_et_set_key(cgo_et_t *et, int aesbits, bool encrypt,
65 const uint8_t *key)
66{
67 size_t aes_key_bytes = aesbits / 8;
68 aes_raw_set_key(&et->kb, key, aesbits, encrypt);
69 polyvalx_init(&et->ku, key + aes_key_bytes);
70}
71
72/** Helper: Compute polyval(KU, H | CMD | X_R). */
73static inline void
74compute_et_mask(polyvalx_t *pvk, const et_tweak_t tweak, uint8_t *t_out)
75{
76 // block 0: tweak.h
77 // block 1: one byte of command, first 15 bytes of x_r
78 // block 2...: remainder of x_r, zero-padded.
79 polyvalx_reset(pvk);
80 uint8_t block1[16];
81 block1[0] = tweak.uiv.cmd;
82 memcpy(block1+1, tweak.x_r, 15);
83 polyvalx_add_block(pvk, tweak.uiv.h);
84 polyvalx_add_block(pvk, block1);
85 polyvalx_add_zpad(pvk, tweak.x_r + 15, ET_TWEAK_LEN_X_R - 15);
86 polyvalx_get_tag(pvk, t_out);
87}
88/** XOR the 16 byte block from inp into out. */
89static void
90xor_block(uint8_t *out, const uint8_t *inp)
91{
92 for (int i = 0; i < 16; ++i)
93 out[i] ^= inp[i];
94}
95
96/**
97 * Encrypt the 16-byte block in 'block'.
98 */
99STATIC void
100cgo_et_encrypt(cgo_et_t *et, const et_tweak_t tweak,
101 uint8_t *block)
102{
103 uint8_t mask[16];
104 compute_et_mask(&et->ku, tweak, mask);
105 xor_block(block, mask);
106 aes_raw_encrypt(et->kb, block);
107 xor_block(block, mask);
108}
109/**
110 * Decrypt the 16-byte b lock in 'block'
111 */
112STATIC void
113cgo_et_decrypt(cgo_et_t *et, const et_tweak_t tweak,
114 uint8_t *block)
115{
116 uint8_t mask[16];
117 compute_et_mask(&et->ku, tweak, mask);
118 xor_block(block, mask);
119 aes_raw_decrypt(et->kb, block);
120 xor_block(block, mask);
121}
122/**
123 * Release any storage held in 'et'.
124 *
125 * This _doesn't_ wipe 'et'; that's done from a higher-level function.
126 */
127STATIC void
128cgo_et_clear(cgo_et_t *et)
129{
130 aes_raw_free(et->kb);
131}
132
133static int
134cgo_prf_keylen(int aesbits)
135{
136 return (aesbits / 8) + POLYVAL_KEY_LEN;
137}
138
139/**
140 * Initialize a psedorandom function from a given key.
141 * Uses an internal 'aesbits'-bit AES key.
142 *
143 * The total key material used from 'key' will be
144 * (aesbits / 8) + 16.
145 */
146STATIC int
147cgo_prf_init(cgo_prf_t *prf, int aesbits,
148 const uint8_t *key)
149{
150 const uint8_t iv[16] = {0};
151 size_t aes_key_bytes = aesbits / 8;
152 memset(prf,0, sizeof(*prf));
153 prf->k = aes_new_cipher(key, iv, aesbits);
154 polyval_key_init(&prf->b, key + aes_key_bytes);
155 return 0;
156}
157/** Replace the key on an existing cgo_prf_t.
158 *
159 * Does fewer allocations than a clear+init. */
160STATIC void
161cgo_prf_set_key(cgo_prf_t *prf, int aesbits,
162 const uint8_t *key)
163{
164 size_t aes_key_bytes = aesbits / 8;
165 aes_cipher_set_key(prf->k, key, aesbits);
166 polyval_key_init(&prf->b, key + aes_key_bytes);
167}
168/**
169 * Compute the PRF's results on 'input', for position t=0,
170 * XOR it into 'data'.
171 *
172 * 'input' must be PRF_INPUT_LEN bytes long.
173 *
174 * 'data' must be PRF_T0_DATA_LEN bytes long.
175 */
176STATIC void
177cgo_prf_xor_t0(cgo_prf_t *prf, const uint8_t *input,
178 uint8_t *data)
179{
180 uint8_t hash[16];
181 polyval_t pv;
182 polyval_init_from_key(&pv, &prf->b);
183 polyval_add_block(&pv, input);
184 polyval_get_tag(&pv, hash);
185 hash[15] &= 0xC0; // Clear the low six bits.
186
187 aes_cipher_set_iv_aligned(prf->k, hash);
188 aes_crypt_inplace(prf->k, (char*) data, PRF_T0_DATA_LEN);
189
190 // Re-align the cipher.
191 //
192 // This approach is faster than EVP_CIPHER_set_num!
193 const int ns = 16 - (PRF_T0_DATA_LEN % 0xf);
194 // We're not using the hash for anything, so it's okay to overwrite
195 aes_crypt_inplace(prf->k, (char*)hash, ns);
196}
197/**
198 * Generate 'n' bytes of the PRF's results on 'input', for position t=1,
199 * and store them into 'buf'.
200 *
201 * 'input' must be PRF_INPUT_LEN bytes long.
202 */
203STATIC void
204cgo_prf_gen_t1(cgo_prf_t *prf, const uint8_t *input,
205 uint8_t *buf, size_t n)
206{
207 #define T1_OFFSET 31
208 uint8_t hash[16];
209 polyval_t pv;
210 polyval_init_from_key(&pv, &prf->b);
211 polyval_add_block(&pv, input);
212 polyval_get_tag(&pv, hash);
213 hash[15] &= 0xC0; // Clear the low six bits.
214 hash[15] += T1_OFFSET; // Can't overflow!
215
216 memset(buf, 0, n);
217 aes_cipher_set_iv_aligned(prf->k, hash);
218 aes_crypt_inplace(prf->k, (char*)buf, n);
219
220 // Re-align the cipher.
221 size_t ns = 16-(n&0x0f);
222 if (ns) {
223 // We're not using the hash for anything, so it's okay to overwrite
224 aes_crypt_inplace(prf->k, (char*) hash, ns);
225 }
226}
227/**
228 * Release any storage held in 'prf'.
229 *
230 * This _doesn't_ wipe 'prf'; that's done from a higher-level function.
231 */
232STATIC void
233cgo_prf_clear(cgo_prf_t *prf)
234{
235 aes_cipher_free(prf->k);
236}
237
238static int
239cgo_uiv_keylen(int aesbits)
240{
241 return cgo_et_keylen(aesbits) + cgo_prf_keylen(aesbits);
242}
243
244/**
245 * Initialize the 'uiv' wide-block cipher, using 'aesbits'-bit
246 * AES keys internally.
247 *
248 * Initializes for encryption or decryption depending on the value of
249 * 'encrypt'.
250 *
251 * The total key material used from 'key' will be
252 * (aesbits / 8) * 2 + 32.
253 */
254STATIC int
255cgo_uiv_init(cgo_uiv_t *uiv, int aesbits, bool encrypt,
256 const uint8_t *key)
257{
258 size_t aes_key_bytes = aesbits / 8;
259 if (cgo_et_init(&uiv->j, aesbits, encrypt, key) < 0)
260 return -1;
261 if (cgo_prf_init(&uiv->s, aesbits, key + aes_key_bytes + POLYVAL_KEY_LEN)<0)
262 return -1;
263#ifdef TOR_UNIT_TESTS
264 /* Testing only: copy the keys so we can test UIV_UPDATE function. */
265 size_t total_key_len = aes_key_bytes * 2 + POLYVAL_KEY_LEN * 2;
266 tor_assert(total_key_len <= sizeof(uiv->uiv_keys_));
267 memset(uiv->uiv_keys_, 0, sizeof(uiv->uiv_keys_));
268 memcpy(uiv->uiv_keys_, key, total_key_len);
269#endif
270 return 0;
271}
272/**
273 * Encrypt 'cell_body', with the provided tweak.
274 *
275 * The cell body must be UIV_BLOCK_LEN bytes long.
276 */
277STATIC void
278cgo_uiv_encrypt(cgo_uiv_t *uiv, const uiv_tweak_t tweak, uint8_t *cell_body)
279{
280 uint8_t *X_L = cell_body;
281 uint8_t *X_R = cell_body + 16;
282
283 const et_tweak_t et_tweak = {
284 .uiv = tweak,
285 .x_r = X_R,
286 };
287 cgo_et_encrypt(&uiv->j, et_tweak, X_L);
288 cgo_prf_xor_t0(&uiv->s, X_L, X_R);
289}
290/**
291 * Decrypt 'cell_body', with the provided tweak.
292 *
293 * The cell body must be UIV_BLOCK_LEN bytes long.
294 */
295STATIC void
296cgo_uiv_decrypt(cgo_uiv_t *uiv, const uiv_tweak_t tweak, uint8_t *cell_body)
297{
298 uint8_t *X_L = cell_body;
299 uint8_t *X_R = cell_body + 16;
300
301 const et_tweak_t et_tweak = {
302 .uiv = tweak,
303 .x_r = X_R,
304 };
305 cgo_prf_xor_t0(&uiv->s, X_L, X_R);
306 cgo_et_decrypt(&uiv->j, et_tweak, X_L);
307}
308/**
309 * Irreversibly ransform the keys of this UIV+, and the provided nonce,
310 * using the nonce as input.
311 *
312 * The nonce must be 16 bytes long.
313 */
314STATIC void
315cgo_uiv_update(cgo_uiv_t *uiv, int aesbits, bool encrypt, uint8_t *nonce)
316{
317 size_t aes_bytes = aesbits / 8;
318 size_t single_key_len = aes_bytes + POLYVAL_KEY_LEN;
319 size_t total_key_len = single_key_len * 2 + 16;
320 // Note: We could store this on the stack, but stack-protector
321 // wouldn't like that.
322 uint8_t *new_keys = tor_malloc(total_key_len);
323
324 cgo_prf_gen_t1(&uiv->s, nonce, new_keys, total_key_len);
325
326 cgo_et_set_key(&uiv->j, aesbits, encrypt, new_keys);
327 cgo_prf_set_key(&uiv->s, aesbits, new_keys + single_key_len);
328
329 memcpy(nonce, new_keys + single_key_len * 2, 16);
330
331#ifdef TOR_UNIT_TESTS
332 /* Testing only: copy the keys so we can test UIV_UPDATE function. */
333 memset(uiv->uiv_keys_, 0, sizeof(uiv->uiv_keys_));
334 memcpy(uiv->uiv_keys_, new_keys, total_key_len);
335#endif
336
337 // This is key material, so we should really discard it.
338 memwipe(new_keys, 0, total_key_len);
339 tor_free(new_keys);
340}
341/**
342 * Release any storage held in 'prf'.
343 *
344 * This _doesn't_ wipe 'prf'; that's done from a higher-level function.
345 */
346STATIC void
347cgo_uiv_clear(cgo_uiv_t *uiv)
348{
349 cgo_et_clear(&uiv->j);
350 cgo_prf_clear(&uiv->s);
351}
352
353/* ====================
354 * High level counter galois onion implementations.
355 */
356
357/**
358 * Return the total number of bytes needed to initialize a cgo_crypt_t.
359 */
360size_t
362{
363 tor_assert(aesbits == 128 || aesbits == 192 || aesbits == 256);
364 return (cgo_uiv_keylen(aesbits) + CGO_TAG_LEN);
365}
366
367/**
368 * Instantiate a CGO authenticated encryption object from the provided
369 * 'keylen' bytes in 'keys'.
370 *
371 * 'keylen' must equal 'cgo_key_material_len(aesbits)'.
372 *
373 * The client and relay must have two cgo_crypt_t objects each:
374 * one for the forward direction, and one for the reverse direction.
375 */
377cgo_crypt_new(cgo_mode_t mode, int aesbits, const uint8_t *keys, size_t keylen)
378{
379 tor_assert(keylen == cgo_key_material_len(aesbits));
380 const uint8_t *end_of_keys = keys + keylen;
381 // Relays encrypt; clients decrypt.
382 // Don't reverse this: UIV+ is only non-malleable for _encryption_.
383 bool encrypt = (mode == CGO_MODE_RELAY_BACKWARD ||
384 mode == CGO_MODE_RELAY_FORWARD);
385 int r;
386
387 cgo_crypt_t *cgo = tor_malloc_zero(sizeof(cgo_crypt_t));
388 r = cgo_uiv_init(&cgo->uiv, aesbits, encrypt, keys);
389 tor_assert(r == 0);
390 keys += cgo_uiv_keylen(aesbits);
391 memcpy(cgo->nonce, keys, CGO_TAG_LEN);
392 keys += CGO_TAG_LEN;
393 tor_assert(keys == end_of_keys);
394
395 cgo->aes_bytes = aesbits / 8;
396
397 return cgo;
398}
399/**
400 * Clean up 'cgo' and free it.
401 */
402void
404{
405 if (!cgo)
406 return;
407 cgo_uiv_clear(&cgo->uiv);
408 memwipe(cgo, 0, sizeof(cgo_crypt_t));
409 tor_free(cgo);
410}
411
412/**
413 * Internal: Run the UIV Update operation on our UIV+ instance.
414 */
415static void
416cgo_crypt_update(cgo_crypt_t *cgo, cgo_mode_t mode)
417{
418 bool encrypt = (mode == CGO_MODE_RELAY_BACKWARD ||
419 mode == CGO_MODE_RELAY_FORWARD);
420 cgo_uiv_update(&cgo->uiv, cgo->aes_bytes * 8, encrypt, cgo->nonce);
421}
422
423/**
424 * Forward CGO encryption operation at a relay:
425 * process an outbound cell from the client.
426 *
427 * If the cell is for this relay, set *'recognized_tag_out'
428 * to point to a CGO_TAG_LEN value that should be used
429 * if we want to acknowledge this cell with an authenticated SENDME.
430 *
431 * The value of 'recognized_tag_out' will become invalid
432 * as soon as any change is made to this 'cgo' object,
433 * or to the cell; if you need it, you should copy it immediately.
434 *
435 * If the cell is not for this relay, set *'recognized_tag_out' to NULL.
436 */
437void
439 const uint8_t **recognized_tag_out)
440{
441 uiv_tweak_t h = {
442 .h = cgo->tprime,
443 .cmd = cell->command,
444 };
445 memcpy(cgo->last_tag_relay_fwd, cell->payload, CGO_TAG_LEN);
446 cgo_uiv_encrypt(&cgo->uiv, h, cell->payload);
447 memcpy(cgo->tprime, cell->payload, CGO_TAG_LEN);
448 if (tor_memeq(cell->payload, cgo->nonce, CGO_TAG_LEN)) {
449 cgo_crypt_update(cgo, CGO_MODE_RELAY_FORWARD);
450 *recognized_tag_out = cgo->last_tag_relay_fwd;
451 } else {
452 *recognized_tag_out = NULL;
453 }
454}
455
456/**
457 * Backward CGO encryption operation at a relay:
458 * process an inbound cell from another relay, for the client.
459 */
460void
462{
463 uiv_tweak_t h = {
464 .h = cgo->tprime,
465 .cmd = cell->command,
466 };
467 cgo_uiv_encrypt(&cgo->uiv, h, cell->payload);
468 memcpy(cgo->tprime, cell->payload, CGO_TAG_LEN);
469}
470
471/**
472 * Backward CGO encryption operation at a relay:
473 * encrypt an inbound message that we are originating, for the client.
474 *
475 * The provided cell must have its command value set,
476 * and should have the first CGO_TAG_LEN bytes of its payload unused.
477 *
478 * Set '*tag_out' to a value that we should expect
479 * if we want an authenticated SENDME for this cell.
480 *
481 * The value of 'recognized_tag_out' will become invalid
482 * as soon as any change is made to this 'cgo' object,
483 * or to the cell; if you need it, you should copy it immediately.
484 */
485void
487 const uint8_t **tag_out)
488{
489 uiv_tweak_t h = {
490 .h = cgo->tprime,
491 .cmd = cell->command,
492 };
493 memcpy(cell->payload, cgo->nonce, CGO_TAG_LEN);
494 cgo_uiv_encrypt(&cgo->uiv, h, cell->payload);
495 memcpy(&cgo->tprime, cell->payload, CGO_TAG_LEN);
496 memcpy(&cgo->nonce, cell->payload, CGO_TAG_LEN);
497 if (tag_out) {
498 // tor_assert(tor_memeq(cgo->tprime, cell->payload, CGO_TAG_LEN));
499 *tag_out = cgo->tprime;
500 }
501 cgo_crypt_update(cgo, CGO_MODE_RELAY_BACKWARD);
502}
503
504/**
505 * Forward CGO encryption at a client:
506 * process a cell for a non-destination hop.
507 **/
508void
510{
511 uint8_t tprime_new[CGO_TAG_LEN];
512 memcpy(tprime_new, cell->payload, CGO_TAG_LEN);
513 uiv_tweak_t h = {
514 .h = cgo->tprime,
515 .cmd = cell->command,
516 };
517 cgo_uiv_decrypt(&cgo->uiv, h, cell->payload);
518 memcpy(cgo->tprime, tprime_new, CGO_TAG_LEN);
519}
520
521/**
522 * Forward CGO encryption at a client:
523 * originate a cell for a given target hop.
524 *
525 * The provided cell must have its command value set,
526 * and should have the first CGO_TAG_LEN bytes of its payload unused.
527 *
528 * Set '*tag_out' to a value that we should expect
529 * if we want an authenticated SENDME for this cell.
530 *
531 * The value of 'recognized_tag_out' will become invalid
532 * as soon as any change is made to this 'cgo' object,
533 * or to the cell; if you need it, you should copy it immediately.
534 */
535void
537 const uint8_t **tag_out)
538{
539 memcpy(cell->payload, cgo->nonce, CGO_TAG_LEN);
540 cgo_crypt_client_forward(cgo, cell);
541 cgo_crypt_update(cgo, CGO_MODE_CLIENT_FORWARD);
542 *tag_out = cell->payload;
543}
544
545/**
546 * Backward CGO encryption operation at a rclient.
547 * process an inbound cell from a relay.
548 *
549 * If the cell originated from this this relay, set *'recognized_tag_out'
550 * to point to a CGO_TAG_LEN value that should be used
551 * if we want to acknowledge this cell with an authenticated SENDME.
552 *
553 * The value of 'recognized_tag_out' will become invalid
554 * as soon as any change is made to this 'cgo' object,
555 * or to the cell; if you need it, you should copy it immediately.
556 *
557 * If the cell is not from this relay, set *'recognized_tag_out' to NULL.
558 */
559void
561 const uint8_t **recognized_tag_out)
562{
563 uiv_tweak_t h = {
564 .h = cgo->tprime,
565 .cmd = cell->command,
566 };
567 uint8_t t_orig[CGO_TAG_LEN];
568 memcpy(t_orig, cell->payload, CGO_TAG_LEN);
569
570 cgo_uiv_decrypt(&cgo->uiv, h, cell->payload);
571 memcpy(cgo->tprime, t_orig, CGO_TAG_LEN);
572 if (tor_memeq(cell->payload, cgo->nonce, CGO_TAG_LEN)) {
573 memcpy(cgo->nonce, t_orig, CGO_TAG_LEN);
574 cgo_crypt_update(cgo, CGO_MODE_CLIENT_BACKWARD);
575 // tor_assert(tor_memeq(cgo->tprime, t_orig, CGO_TAG_LEN));
576 *recognized_tag_out = cgo->tprime;
577 } else {
578 *recognized_tag_out = NULL;
579 }
580}
Headers for aes.c.
void aes_cipher_set_key(aes_cnt_cipher_t *cipher_, const uint8_t *key, int key_bits)
Definition: aes_nss.c:115
void aes_cipher_set_iv_aligned(aes_cnt_cipher_t *cipher_, const uint8_t *iv)
Definition: aes_nss.c:105
void aes_raw_set_key(aes_raw_t **cipher_, const uint8_t *key, int key_bits, bool encrypt)
Definition: aes_openssl.c:219
void aes_raw_encrypt(const aes_raw_t *cipher, uint8_t *block)
Definition: aes_openssl.c:259
void aes_raw_decrypt(const aes_raw_t *cipher, uint8_t *block)
Definition: aes_openssl.c:271
aes_raw_t * aes_raw_new(const uint8_t *key, int key_bits, bool encrypt)
Definition: aes_openssl.c:193
Header for binascii.c.
Inline functions for reading and writing multibyte values from the middle of strings,...
Fixed-size cell structure.
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:55
Common functions for cryptographic routines.
int tor_memeq(const void *a, const void *b, size_t sz)
Definition: di_ops.c:107
#define tor_free(p)
Definition: malloc.h:56
Master header file for Tor-specific functionality.
Implementation for polyval universal hash function.
#define POLYVAL_KEY_LEN
Definition: polyval.h:100
void polyval_add_block(polyval_t *, const uint8_t *block)
void polyval_get_tag(const polyval_t *, uint8_t *tag_out)
void polyval_init_from_key(polyval_t *, const polyval_key_t *key)
void polyval_key_init(polyval_key_t *, const uint8_t *key)
STATIC int cgo_et_init(cgo_et_t *et, int aesbits, bool encrypt, const uint8_t *key)
STATIC int cgo_uiv_init(cgo_uiv_t *uiv, int aesbits, bool encrypt, const uint8_t *key)
STATIC void cgo_prf_xor_t0(cgo_prf_t *prf, const uint8_t *input, uint8_t *data)
STATIC void cgo_uiv_clear(cgo_uiv_t *uiv)
void cgo_crypt_relay_originate(cgo_crypt_t *cgo, cell_t *cell, const uint8_t **tag_out)
void cgo_crypt_client_forward(cgo_crypt_t *cgo, cell_t *cell)
static void compute_et_mask(polyvalx_t *pvk, const et_tweak_t tweak, uint8_t *t_out)
void cgo_crypt_relay_backward(cgo_crypt_t *cgo, cell_t *cell)
STATIC void cgo_et_decrypt(cgo_et_t *et, const et_tweak_t tweak, uint8_t *block)
STATIC void cgo_et_set_key(cgo_et_t *et, int aesbits, bool encrypt, const uint8_t *key)
STATIC void cgo_uiv_encrypt(cgo_uiv_t *uiv, const uiv_tweak_t tweak, uint8_t *cell_body)
STATIC void cgo_et_clear(cgo_et_t *et)
STATIC int cgo_prf_init(cgo_prf_t *prf, int aesbits, const uint8_t *key)
size_t cgo_key_material_len(int aesbits)
static void xor_block(uint8_t *out, const uint8_t *inp)
STATIC void cgo_prf_clear(cgo_prf_t *prf)
void cgo_crypt_relay_forward(cgo_crypt_t *cgo, cell_t *cell, const uint8_t **recognized_tag_out)
STATIC void cgo_uiv_update(cgo_uiv_t *uiv, int aesbits, bool encrypt, uint8_t *nonce)
void cgo_crypt_free_(cgo_crypt_t *cgo)
static void cgo_crypt_update(cgo_crypt_t *cgo, cgo_mode_t mode)
STATIC void cgo_prf_set_key(cgo_prf_t *prf, int aesbits, const uint8_t *key)
cgo_crypt_t * cgo_crypt_new(cgo_mode_t mode, int aesbits, const uint8_t *keys, size_t keylen)
STATIC void cgo_prf_gen_t1(cgo_prf_t *prf, const uint8_t *input, uint8_t *buf, size_t n)
void cgo_crypt_client_originate(cgo_crypt_t *cgo, cell_t *cell, const uint8_t **tag_out)
STATIC void cgo_et_encrypt(cgo_et_t *et, const et_tweak_t tweak, uint8_t *block)
void cgo_crypt_client_backward(cgo_crypt_t *cgo, cell_t *cell, const uint8_t **recognized_tag_out)
STATIC void cgo_uiv_decrypt(cgo_uiv_t *uiv, const uiv_tweak_t tweak, uint8_t *cell_body)
Header file for relay_crypto_cgo.c.
#define CGO_TAG_LEN
struct cgo_crypt_t cgo_crypt_t
Definition: cell_st.h:17
uint8_t payload[CELL_PAYLOAD_SIZE]
Definition: cell_st.h:21
uint8_t command
Definition: cell_st.h:19
#define STATIC
Definition: testsupport.h:32
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:103