relay_crypto_cgo.c (16353B)
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" 19 #include "lib/crypt_ops/crypto_util.h" 20 #include "lib/log/util_bug.h" 21 #include "lib/arch/bytes.h" 22 #include "ext/polyval/polyval.h" 23 #include "core/crypto/relay_crypto_cgo.h" 24 #include "core/crypto/relay_crypto.h" 25 #include "core/or/cell_st.h" 26 27 #if 0 28 // XXXX debugging. 29 #include "lib/encoding/binascii.h" 30 #include <stdio.h> 31 #endif 32 33 #include <string.h> 34 35 static int 36 cgo_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 */ 50 STATIC int 51 cgo_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. */ 64 STATIC void 65 cgo_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). */ 74 static inline void 75 compute_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. */ 90 static void 91 xor_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 */ 100 STATIC void 101 cgo_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 */ 113 STATIC void 114 cgo_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 */ 128 STATIC void 129 cgo_et_clear(cgo_et_t *et) 130 { 131 aes_raw_free(et->kb); 132 } 133 134 static int 135 cgo_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 */ 147 STATIC int 148 cgo_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. */ 161 STATIC void 162 cgo_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 */ 177 STATIC void 178 cgo_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 */ 204 STATIC void 205 cgo_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 */ 233 STATIC void 234 cgo_prf_clear(cgo_prf_t *prf) 235 { 236 aes_cipher_free(prf->k); 237 } 238 239 static int 240 cgo_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 */ 255 STATIC int 256 cgo_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 */ 278 STATIC void 279 cgo_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 */ 296 STATIC void 297 cgo_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 */ 315 STATIC void 316 cgo_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 */ 347 STATIC void 348 cgo_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 */ 361 size_t 362 cgo_key_material_len(int aesbits) 363 { 364 tor_assert(aesbits == 128 || aesbits == 192 || aesbits == 256); 365 size_t r = (cgo_uiv_keylen(aesbits) + SENDME_TAG_LEN_CGO); 366 tor_assert(r * 2 <= MAX_RELAY_KEY_MATERIAL_LEN); 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 */ 379 cgo_crypt_t * 380 cgo_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 */ 405 void 406 cgo_crypt_free_(cgo_crypt_t *cgo) 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 */ 418 static void 419 cgo_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 */ 440 void 441 cgo_crypt_relay_forward(cgo_crypt_t *cgo, cell_t *cell, 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 */ 463 void 464 cgo_crypt_relay_backward(cgo_crypt_t *cgo, cell_t *cell) 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 */ 488 void 489 cgo_crypt_relay_originate(cgo_crypt_t *cgo, cell_t *cell, 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 **/ 511 void 512 cgo_crypt_client_forward(cgo_crypt_t *cgo, cell_t *cell) 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 */ 538 void 539 cgo_crypt_client_originate(cgo_crypt_t *cgo, cell_t *cell, 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 */ 562 void 563 cgo_crypt_client_backward(cgo_crypt_t *cgo, cell_t *cell, 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 }