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