test_crypto_cgo.c (19753B)
1 /* Copyright (c) 2001-2004, Roger Dingledine. 2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 3 * Copyright (c) 2007-2021, The Tor Project, Inc. */ 4 /* See LICENSE for licensing information */ 5 6 #define RELAY_CRYPTO_CGO_PRIVATE 7 #define USE_AES_RAW 8 9 #include "orconfig.h" 10 #include "core/or/or.h" 11 #include "test/test.h" 12 #include "lib/cc/compat_compiler.h" 13 #include "lib/crypt_ops/aes.h" 14 #include "ext/polyval/polyval.h" 15 #include "core/crypto/relay_crypto_cgo.h" 16 #include "lib/crypt_ops/crypto_rand.h" 17 #include "lib/crypt_ops/crypto_util.h" 18 #include "core/or/cell_st.h" 19 20 #include "test/cgo_vectors.inc" 21 22 static const int AESBITS[] = { 128, 192, 256 }; 23 24 static void 25 test_crypto_cgo_et_roundtrip(void *arg) 26 { 27 (void)arg; 28 uint8_t key[32 + 16]; // max 29 uint8_t tweak_h[16]; 30 uint8_t tweak_x_r[493]; 31 uint8_t block[16], block_orig[16]; 32 cgo_et_t et1, et2; 33 memset(&et1, 0, sizeof(et1)); 34 memset(&et2, 0, sizeof(et2)); 35 36 et_tweak_t tweak = { 37 .uiv = { 38 .h = tweak_h, 39 .cmd = 7, 40 }, 41 .x_r = tweak_x_r, 42 }; 43 44 for (int bi = 0; bi < (int) ARRAY_LENGTH(AESBITS); ++bi) { 45 const int aesbits = AESBITS[bi]; 46 47 for (int i = 0; i < 16; ++i) { 48 crypto_rand((char*)key, sizeof(key)); 49 crypto_rand((char*)tweak_h, sizeof(tweak_h)); 50 crypto_rand((char*)tweak_x_r, sizeof(tweak_x_r)); 51 crypto_rand((char*)block_orig, sizeof(block_orig)); 52 memcpy(block, block_orig, 16); 53 cgo_et_init(&et1, aesbits, true, key); 54 cgo_et_init(&et2, aesbits, false, key); 55 56 // encrypt-then-decrypt should round-trip. 57 cgo_et_encrypt(&et1, tweak, block); 58 tt_mem_op(block, OP_NE, block_orig, 16); 59 cgo_et_decrypt(&et2, tweak, block); 60 tt_mem_op(block, OP_EQ, block_orig, 16); 61 62 // decrypt-then-encrypt should round-trip. 63 cgo_et_decrypt(&et2, tweak, block); 64 tt_mem_op(block, OP_NE, block_orig, 16); 65 cgo_et_encrypt(&et1, tweak, block); 66 tt_mem_op(block, OP_EQ, block_orig, 16); 67 68 cgo_et_clear(&et1); 69 cgo_et_clear(&et2); 70 } 71 } 72 done: 73 cgo_et_clear(&et1); 74 cgo_et_clear(&et2); 75 } 76 77 static void 78 test_crypto_cgo_uiv_roundtrip(void *arg) 79 { 80 (void)arg; 81 uint8_t key[64 + 32]; // max 82 uint8_t tweak_h[16]; 83 uint8_t cell[509], cell_orig[509]; 84 cgo_uiv_t uiv1, uiv2; 85 memset(&uiv1, 0, sizeof(uiv1)); 86 memset(&uiv2, 0, sizeof(uiv2)); 87 88 uiv_tweak_t tweak = { 89 .h = tweak_h, 90 .cmd = 4, 91 }; 92 93 for (int bi = 0; bi < (int) ARRAY_LENGTH(AESBITS); ++bi) { 94 const int aesbits = AESBITS[bi]; 95 96 for (int i = 0; i < 16; ++i) { 97 crypto_rand((char*)key, sizeof(key)); 98 crypto_rand((char*)tweak_h, sizeof(tweak_h)); 99 crypto_rand((char*)cell_orig, sizeof(cell_orig)); 100 memcpy(cell, cell_orig, sizeof(cell_orig)); 101 102 cgo_uiv_init(&uiv1, aesbits, true, key); 103 cgo_uiv_init(&uiv2, aesbits, false, key); 104 105 // encrypt-then-decrypt should round-trip. 106 cgo_uiv_encrypt(&uiv1, tweak, cell); 107 tt_mem_op(cell, OP_NE, cell_orig, sizeof(cell)); 108 cgo_uiv_decrypt(&uiv2, tweak, cell); 109 tt_mem_op(cell, OP_EQ, cell_orig, sizeof(cell)); 110 111 // decrypt-then-encrypt should round-trip. 112 cgo_uiv_decrypt(&uiv2, tweak, cell); 113 tt_mem_op(cell, OP_NE, cell_orig, sizeof(cell)); 114 cgo_uiv_encrypt(&uiv1, tweak, cell); 115 tt_mem_op(cell, OP_EQ, cell_orig, sizeof(cell)); 116 117 cgo_uiv_clear(&uiv1); 118 cgo_uiv_clear(&uiv2); 119 } 120 } 121 done: 122 cgo_uiv_clear(&uiv1); 123 cgo_uiv_clear(&uiv2); 124 } 125 126 #define UNHEX(out,inp) STMT_BEGIN { \ 127 size_t inplen = strlen(inp); \ 128 tt_int_op(sizeof(out), OP_EQ, inplen / 2); \ 129 int r = base16_decode((char*)(out), sizeof(out), inp, inplen); \ 130 tt_int_op(r, OP_EQ, sizeof(out)); \ 131 } STMT_END 132 133 #define UNHEX2(out,inp1,inp2) STMT_BEGIN { \ 134 tor_free(unhex_tmp); \ 135 tor_asprintf(&unhex_tmp, "%s%s", inp1, inp2); \ 136 UNHEX(out, unhex_tmp); \ 137 } STMT_END 138 139 static void 140 test_crypto_cgo_et_testvec(void *arg) 141 { 142 (void)arg; 143 cgo_et_t et; 144 memset(&et, 0, sizeof(et)); 145 146 for (int i = 0; i < (int)ARRAY_LENGTH(ET_TESTVECS); ++i) { 147 const struct et_testvec *tv = &ET_TESTVECS[i]; 148 uint8_t keys[32]; 149 uint8_t tweaks[16 + 1 + 493]; 150 uint8_t block[16], expect[16]; 151 UNHEX(keys, tv->keys); 152 UNHEX(tweaks, tv->tweaks); 153 UNHEX(block, tv->block); 154 UNHEX(expect, tv->expect); 155 156 et_tweak_t tweak = { 157 .uiv = { 158 .h = tweaks, 159 .cmd = tweaks[16], 160 }, 161 .x_r = tweaks + 17, 162 }; 163 164 cgo_et_init(&et, 128, tv->encrypt, keys); 165 if (tv->encrypt) { 166 cgo_et_encrypt(&et, tweak, block); 167 } else { 168 cgo_et_decrypt(&et, tweak, block); 169 } 170 cgo_et_clear(&et); 171 172 tt_mem_op(block, OP_EQ, expect, 16); 173 } 174 175 done: 176 cgo_et_clear(&et); 177 } 178 179 static void 180 test_crypto_cgo_prf_testvec(void *arg) 181 { 182 (void)arg; 183 cgo_prf_t prf; 184 memset(&prf, 0, sizeof(prf)); 185 186 for (int i = 0; i < (int)ARRAY_LENGTH(PRF_TESTVECS); ++i) { 187 const struct prf_testvec *tv = &PRF_TESTVECS[i]; 188 uint8_t keys[32]; 189 uint8_t input[16]; 190 uint8_t expect_t0[493]; 191 uint8_t expect_t1[80]; 192 uint8_t output[493]; // max 193 UNHEX(keys, tv->keys); 194 UNHEX(input, tv->input); 195 196 cgo_prf_init(&prf, 128, keys); 197 if (tv->t == 0) { 198 UNHEX(expect_t0, tv->expect); 199 memset(output, 0, sizeof(output)); 200 cgo_prf_xor_t0(&prf, input, output); 201 tt_mem_op(output, OP_EQ, expect_t0, PRF_T0_DATA_LEN); 202 } else { 203 tt_int_op(tv->t, OP_EQ, 1); 204 UNHEX(expect_t1, tv->expect); 205 cgo_prf_gen_t1(&prf, input, output, sizeof(expect_t1)); 206 tt_mem_op(output, OP_EQ, expect_t1, sizeof(expect_t1)); 207 } 208 cgo_prf_clear(&prf); 209 } 210 done: 211 cgo_prf_clear(&prf); 212 } 213 214 static void 215 test_crypto_cgo_uiv_testvec(void *arg) 216 { 217 (void)arg; 218 cgo_uiv_t uiv; 219 memset(&uiv, 0, sizeof(uiv)); 220 221 for (int i = 0; i < (int)ARRAY_LENGTH(UIV_TESTVECS); ++i) { 222 const struct uiv_testvec *tv = &UIV_TESTVECS[i]; 223 uint8_t keys[64]; 224 uint8_t tweaks[17]; 225 uint8_t x_l[16], x_r[493]; 226 uint8_t y_l[16], y_r[493]; 227 uint8_t cell[509]; 228 UNHEX(keys, tv->keys); 229 UNHEX(tweaks, tv->tweaks); 230 UNHEX(x_l, tv->x_l); 231 UNHEX(x_r, tv->x_r); 232 UNHEX(y_l, tv->y.y_l); 233 UNHEX(y_r, tv->y.y_r); 234 235 uiv_tweak_t tweak = { 236 .h = tweaks, 237 .cmd = tweaks[16] 238 }; 239 memcpy(cell, x_l, 16); 240 memcpy(cell+16, x_r, 493); 241 242 cgo_uiv_init(&uiv, 128, tv->encrypt, keys); 243 if (tv->encrypt) { 244 cgo_uiv_encrypt(&uiv, tweak, cell); 245 } else { 246 cgo_uiv_decrypt(&uiv, tweak, cell); 247 } 248 cgo_uiv_clear(&uiv); 249 250 tt_mem_op(cell, OP_EQ, y_l, 16); 251 tt_mem_op(cell+16, OP_EQ, y_r, 493); 252 } 253 254 done: 255 cgo_uiv_clear(&uiv); 256 } 257 258 #include "core/crypto/relay_crypto_st.h" 259 260 static void 261 test_crypto_cgo_uiv_update_testvec(void *arg) 262 { 263 (void)arg; 264 cgo_uiv_t uiv; 265 cgo_uiv_t uiv2; 266 memset(&uiv, 0, sizeof(uiv)); 267 memset(&uiv2, 0, sizeof(uiv2)); 268 269 uint8_t tw[16]; 270 memset(tw, 42, sizeof(tw)); 271 uiv_tweak_t tweak = { 272 .h = tw, 273 .cmd = 42 274 }; 275 276 for (int i = 0; i < (int)ARRAY_LENGTH(UIV_UPDATE_TESTVECS); ++i) { 277 const struct uiv_update_testvec *tv = &UIV_UPDATE_TESTVECS[i]; 278 uint8_t keys[64]; 279 uint8_t nonce[16]; 280 uint8_t new_keys[64]; 281 uint8_t new_nonce[16]; 282 UNHEX(keys, tv->keys); 283 UNHEX(nonce, tv->nonce); 284 UNHEX(new_keys, tv->output.new_keys); 285 UNHEX(new_nonce, tv->output.new_nonce); 286 287 cgo_uiv_init(&uiv, 128, true, keys); 288 cgo_uiv_update(&uiv, 128, true, nonce); 289 // Make sure that the recorded keys are what we expect. 290 tt_mem_op(uiv.uiv_keys_, OP_EQ, new_keys, 64); 291 tt_mem_op(nonce, OP_EQ, new_nonce, 16); 292 293 // Construct a new UIV from these keys and make sure it acts like this one. 294 uint8_t cell[509], cell2[509]; 295 crypto_rand((char*)cell, sizeof(cell)); 296 memcpy(cell2, cell, 509); 297 cgo_uiv_init(&uiv2, 128, true, uiv.uiv_keys_); 298 cgo_uiv_encrypt(&uiv, tweak, cell); 299 cgo_uiv_encrypt(&uiv2, tweak, cell2); 300 tt_mem_op(cell, OP_EQ, cell2, 509); 301 302 cgo_uiv_clear(&uiv); 303 cgo_uiv_clear(&uiv2); 304 } 305 done: 306 cgo_uiv_clear(&uiv); 307 cgo_uiv_clear(&uiv2); 308 } 309 310 static void 311 test_crypto_cgo_fwd(void *arg) 312 { 313 (void)arg; 314 315 #define N_HOPS 3 316 uint8_t key_material[N_HOPS][112]; // max. 317 cgo_crypt_t *client[N_HOPS]; 318 cgo_crypt_t *relays[N_HOPS]; 319 320 memset(client, 0, sizeof(client)); 321 memset(relays, 0, sizeof(relays)); 322 323 for (int bi = 0; bi < (int) ARRAY_LENGTH(AESBITS); ++bi) { 324 const int aesbits = AESBITS[bi]; 325 326 size_t klen = cgo_key_material_len(aesbits); 327 tt_uint_op(klen, OP_LE, sizeof(key_material[0])); 328 crypto_rand((char*)&key_material, sizeof(key_material)); 329 for (int i = 0; i < N_HOPS; ++i) { 330 client[i] = cgo_crypt_new(CGO_MODE_CLIENT_FORWARD, 331 aesbits, key_material[i], klen); 332 relays[i] = cgo_crypt_new(CGO_MODE_RELAY_FORWARD, 333 aesbits, key_material[i], klen); 334 } 335 for (int trial = 0; trial < 64; ++trial) { 336 int target_hop = crypto_rand_int(3); 337 cell_t cell, cell_orig; 338 uint8_t tag_client[SENDME_TAG_LEN_CGO]; 339 const uint8_t *tagp = NULL; 340 341 memset(&cell, 0, sizeof(cell)); 342 if (crypto_rand_int(2) == 0) { 343 cell.command = CELL_RELAY; 344 } else { 345 cell.command = CELL_RELAY_EARLY; 346 } 347 crypto_rand((char*) cell.payload+SENDME_TAG_LEN_CGO, 348 sizeof(cell.payload)-SENDME_TAG_LEN_CGO); 349 memcpy(&cell_orig, &cell, sizeof(cell)); 350 351 // First the client encrypts the cell... 352 cgo_crypt_client_originate(client[target_hop], &cell, &tagp); 353 tt_assert(tagp); 354 memcpy(tag_client, tagp, SENDME_TAG_LEN_CGO); 355 for (int i = target_hop - 1; i >= 0; --i) { 356 cgo_crypt_client_forward(client[i], &cell); 357 } 358 359 // Now the relays handle the cell... 360 bool cell_recognized = false; 361 for (int i = 0; i < N_HOPS; ++i) { 362 tagp = NULL; 363 cgo_crypt_relay_forward(relays[i], &cell, &tagp); 364 if (tagp) { 365 tt_int_op(i, OP_EQ, target_hop); 366 tt_mem_op(tagp, OP_EQ, tag_client, SENDME_TAG_LEN_CGO); 367 cell_recognized = true; 368 break; 369 } 370 } 371 tt_assert(cell_recognized); 372 tt_int_op(cell.command, OP_EQ, cell_orig.command); 373 tt_mem_op(cell.payload + SENDME_TAG_LEN_CGO, OP_EQ, 374 cell_orig.payload + SENDME_TAG_LEN_CGO, 375 sizeof(cell.payload) - SENDME_TAG_LEN_CGO); 376 } 377 for (int i = 0; i < N_HOPS; ++i) { 378 cgo_crypt_free(client[i]); 379 cgo_crypt_free(relays[i]); 380 } 381 } 382 383 done: 384 for (int i = 0; i < N_HOPS; ++i) { 385 cgo_crypt_free(client[i]); 386 cgo_crypt_free(relays[i]); 387 } 388 #undef N_HOPS 389 } 390 391 static void 392 test_crypto_cgo_rev(void *arg) 393 { 394 (void)arg; 395 396 #define N_HOPS 3 397 uint8_t key_material[N_HOPS][112]; // max. 398 cgo_crypt_t *client[N_HOPS]; 399 cgo_crypt_t *relays[N_HOPS]; 400 401 memset(client, 0, sizeof(client)); 402 memset(relays, 0, sizeof(relays)); 403 404 for (int bi = 0; bi < (int) ARRAY_LENGTH(AESBITS); ++bi) { 405 const int aesbits = AESBITS[bi]; 406 407 size_t klen = cgo_key_material_len(aesbits); 408 tt_uint_op(klen, OP_LE, sizeof(key_material[0])); 409 crypto_rand((char*)&key_material, sizeof(key_material)); 410 for (int i = 0; i < N_HOPS; ++i) { 411 client[i] = cgo_crypt_new(CGO_MODE_CLIENT_BACKWARD, 412 aesbits, key_material[i], klen); 413 relays[i] = cgo_crypt_new(CGO_MODE_RELAY_BACKWARD, 414 aesbits, key_material[i], klen); 415 } 416 for (int trial = 0; trial < 64; ++trial) { 417 int origin_hop = crypto_rand_int(3); 418 cell_t cell, cell_orig; 419 uint8_t tag_relay[SENDME_TAG_LEN_CGO]; 420 const uint8_t *tagp = NULL; 421 422 memset(&cell, 0, sizeof(cell)); 423 cell.command = CELL_RELAY; 424 crypto_rand((char*) cell.payload+SENDME_TAG_LEN_CGO, 425 sizeof(cell.payload)-SENDME_TAG_LEN_CGO); 426 memcpy(&cell_orig, &cell, sizeof(cell)); 427 428 // First the specified relay encrypts the cell... 429 cgo_crypt_relay_originate(relays[origin_hop], &cell, &tagp); 430 tt_assert(tagp); 431 memcpy(tag_relay, tagp, SENDME_TAG_LEN_CGO); 432 for (int i = origin_hop - 1; i >= 0; --i) { 433 cgo_crypt_relay_backward(relays[i], &cell); 434 } 435 436 // Now the client handles the cell. 437 bool cell_recognized = false; 438 for (int i = 0; i < N_HOPS; ++i) { 439 tagp = NULL; 440 cgo_crypt_client_backward(client[i], &cell, &tagp); 441 if (tagp) { 442 tt_int_op(i, OP_EQ, origin_hop); 443 tt_mem_op(tagp, OP_EQ, tag_relay, SENDME_TAG_LEN_CGO); 444 cell_recognized = true; 445 break; 446 } 447 } 448 tt_assert(cell_recognized); 449 tt_int_op(cell.command, OP_EQ, cell_orig.command); 450 tt_mem_op(cell.payload + SENDME_TAG_LEN_CGO, OP_EQ, 451 cell_orig.payload + SENDME_TAG_LEN_CGO, 452 sizeof(cell.payload) - SENDME_TAG_LEN_CGO); 453 } 454 for (int i = 0; i < N_HOPS; ++i) { 455 cgo_crypt_free(client[i]); 456 cgo_crypt_free(relays[i]); 457 } 458 } 459 460 done: 461 for (int i = 0; i < N_HOPS; ++i) { 462 cgo_crypt_free(client[i]); 463 cgo_crypt_free(relays[i]); 464 } 465 #undef N_HOPS 466 } 467 468 static void 469 test_crypto_cgo_relay_testvec(void *arg) 470 { 471 (void)arg; 472 char *unhex_tmp = NULL; 473 cgo_crypt_t *cgo = NULL; 474 for (int i = 0; i < (int)ARRAY_LENGTH(CGO_RELAY_TESTVECS); ++i) { 475 const struct cgo_relay_testvec *tv = &CGO_RELAY_TESTVECS[i]; 476 const int aesbits = 128; 477 uint8_t keys[80], expect_keys[80], expect_tprime[SENDME_TAG_LEN_CGO], 478 cmd[1]; 479 cell_t cell; 480 cell_t expect_cell; 481 tt_int_op(sizeof(keys), OP_EQ, cgo_key_material_len(aesbits)); 482 UNHEX2(keys, tv->state_in.keys, tv->state_in.nonce); 483 cgo_mode_t mode = 484 tv->inbound ? CGO_MODE_RELAY_BACKWARD : CGO_MODE_RELAY_FORWARD; 485 cgo = cgo_crypt_new(mode, aesbits, keys, sizeof(keys)); 486 tt_assert(cgo); 487 UNHEX(cgo->tprime, tv->state_in.tprime); 488 memset(&cell, 0, sizeof(cell)); 489 UNHEX(cmd, tv->cmd); 490 cell.command = cmd[0]; 491 UNHEX2(cell.payload, tv->tag, tv->msg); 492 493 memset(&expect_cell, 0, sizeof(expect_cell)); 494 expect_cell.command = cell.command; 495 UNHEX2(expect_cell.payload, 496 tv->output.result.t_out, tv->output.result.msg_out); 497 UNHEX2(expect_keys, 498 tv->output.state.keys, tv->output.state.nonce); 499 UNHEX(expect_tprime, tv->output.state.tprime); 500 501 if (tv->inbound) { 502 cgo_crypt_relay_backward(cgo, &cell); 503 } else { 504 const uint8_t *tagp = NULL; 505 cgo_crypt_relay_forward(cgo, &cell, &tagp); 506 tt_ptr_op(tagp, OP_EQ, NULL); 507 } 508 509 tt_mem_op(cell.payload, OP_EQ, expect_cell.payload, sizeof(cell.payload)); 510 tt_mem_op(cgo->uiv.uiv_keys_, OP_EQ, expect_keys, 64); 511 tt_mem_op(cgo->nonce, OP_EQ, expect_keys + 64, 16); 512 tt_mem_op(cgo->tprime, OP_EQ, expect_tprime, 16); 513 514 cgo_crypt_free(cgo); 515 } 516 done: 517 tor_free(unhex_tmp); 518 cgo_crypt_free(cgo); 519 } 520 521 static void 522 test_crypto_cgo_relay_originate_testvec(void *arg) 523 { 524 (void)arg; 525 char *unhex_tmp = NULL; 526 cgo_crypt_t *cgo = NULL; 527 for (int i = 0; i < (int)ARRAY_LENGTH(CGO_RELAY_ORIGINATE_TESTVECS); ++i) { 528 const struct cgo_relay_originate_testvec *tv = 529 &CGO_RELAY_ORIGINATE_TESTVECS[i]; 530 const int aesbits = 128; 531 uint8_t keys[80], expect_keys[80], expect_tprime[SENDME_TAG_LEN_CGO], 532 cmd[1]; 533 cell_t cell; 534 cell_t expect_cell; 535 tt_int_op(sizeof(keys), OP_EQ, cgo_key_material_len(aesbits)); 536 UNHEX2(keys, tv->state_in.keys, tv->state_in.nonce); 537 cgo = cgo_crypt_new(CGO_MODE_RELAY_BACKWARD, aesbits, keys, sizeof(keys)); 538 tt_assert(cgo); 539 UNHEX(cgo->tprime, tv->state_in.tprime); 540 memset(&cell, 0, sizeof(cell)); 541 UNHEX(cmd, tv->cmd); 542 cell.command = cmd[0]; 543 UNHEX2(cell.payload, "00000000000000000000000000000000", tv->msg); 544 545 memset(&expect_cell, 0, sizeof(expect_cell)); 546 expect_cell.command = cell.command; 547 UNHEX2(expect_cell.payload, 548 tv->output.result.t_out, tv->output.result.msg_out); 549 UNHEX2(expect_keys, 550 tv->output.state.keys, tv->output.state.nonce); 551 UNHEX(expect_tprime, tv->output.state.tprime); 552 553 const uint8_t *tagp = NULL; 554 cgo_crypt_relay_originate(cgo, &cell, &tagp); 555 tt_ptr_op(tagp, OP_NE, NULL); 556 557 tt_mem_op(cell.payload, OP_EQ, expect_cell.payload, sizeof(cell.payload)); 558 tt_mem_op(cgo->uiv.uiv_keys_, OP_EQ, expect_keys, 64); 559 tt_mem_op(cgo->nonce, OP_EQ, expect_keys + 64, 16); 560 tt_mem_op(cgo->tprime, OP_EQ, expect_tprime, 16); 561 562 cgo_crypt_free(cgo); 563 } 564 done: 565 tor_free(unhex_tmp); 566 cgo_crypt_free(cgo); 567 } 568 569 static void 570 test_crypto_cgo_client_originate_testvec(void *arg) 571 { 572 (void) arg; 573 char *unhex_tmp = NULL; 574 cgo_crypt_t *cgo[3] = { NULL, NULL, NULL }; 575 for (int tv_i = 0; tv_i < (int)ARRAY_LENGTH(CGO_CLIENT_ORIGINATE_TESTVECS); 576 ++tv_i) { 577 const struct cgo_client_originate_testvec *tv = 578 &CGO_CLIENT_ORIGINATE_TESTVECS[tv_i]; 579 const int aesbits = 128; 580 uint8_t keys[80], expect_keys[80], expect_tprime[SENDME_TAG_LEN_CGO], 581 cmd[1]; 582 cell_t cell; 583 cell_t expect_cell; 584 for (int i = 0; i < 3; ++i) { 585 tt_int_op(sizeof(keys), OP_EQ, cgo_key_material_len(aesbits)); 586 UNHEX2(keys, tv->state_in[i].keys, tv->state_in[i].nonce); 587 cgo[i] = cgo_crypt_new(CGO_MODE_CLIENT_FORWARD, 588 aesbits, keys, sizeof(keys)); 589 tt_assert(cgo[i]); 590 UNHEX(cgo[i]->tprime, tv->state_in[i].tprime); 591 } 592 593 memset(&cell, 0, sizeof(cell)); 594 UNHEX(cmd, tv->cmd); 595 cell.command = cmd[0]; 596 UNHEX2(cell.payload, "00000000000000000000000000000000", tv->msg); 597 598 memset(&expect_cell, 0, sizeof(expect_cell)); 599 expect_cell.command = cell.command; 600 UNHEX2(expect_cell.payload, 601 tv->output.result.t_out, tv->output.result.msg_out); 602 603 tt_int_op(tv->target_hop, OP_GE, 1); // Hop is 0-indexed. 604 int target_hop = tv->target_hop - 1; 605 const uint8_t *tagp = NULL; 606 cgo_crypt_client_originate(cgo[target_hop], &cell, &tagp); 607 tt_ptr_op(tagp, OP_NE, NULL); 608 for (int i = target_hop - 1; i >= 0; --i) { 609 cgo_crypt_client_forward(cgo[i], &cell); 610 } 611 tt_mem_op(cell.payload, OP_EQ, expect_cell.payload, sizeof(cell.payload)); 612 613 for (int i = 0; i < 3; ++i) { 614 UNHEX2(expect_keys, 615 tv->output.state[i].keys, tv->output.state[i].nonce); 616 UNHEX(expect_tprime, tv->output.state[i].tprime); 617 618 tt_mem_op(cgo[i]->uiv.uiv_keys_, OP_EQ, expect_keys, 64); 619 tt_mem_op(cgo[i]->nonce, OP_EQ, expect_keys + 64, 16); 620 tt_mem_op(cgo[i]->tprime, OP_EQ, expect_tprime, 16); 621 } 622 623 for (int i = 0; i < 3; ++i) 624 cgo_crypt_free(cgo[i]); 625 } 626 done: 627 tor_free(unhex_tmp); 628 for (int i = 0; i < 3; ++i) 629 cgo_crypt_free(cgo[i]); 630 } 631 632 struct testcase_t crypto_cgo_tests[] = { 633 { "et_roundtrip", test_crypto_cgo_et_roundtrip, 0, NULL, NULL }, 634 { "et_testvec", test_crypto_cgo_et_testvec, 0, NULL, NULL }, 635 { "prf_testvec", test_crypto_cgo_prf_testvec, 0, NULL, NULL }, 636 { "uiv_roundtrip", test_crypto_cgo_uiv_roundtrip, 0, NULL, NULL }, 637 { "uiv_testvec", test_crypto_cgo_uiv_testvec, 0, NULL, NULL }, 638 { "uiv_update_testvec", test_crypto_cgo_uiv_update_testvec, 0, NULL, NULL }, 639 { "cgo_fwd", test_crypto_cgo_fwd, 0, NULL, NULL, }, 640 { "cgo_rev", test_crypto_cgo_rev, 0, NULL, NULL, }, 641 { "cgo_relay_testvec", test_crypto_cgo_relay_testvec, 0, NULL, NULL }, 642 { "cgo_relay_originate_testvec", test_crypto_cgo_relay_originate_testvec, 643 0, NULL, NULL }, 644 { "cgo_client_originate_testvec", test_crypto_cgo_client_originate_testvec, 645 0, NULL, NULL }, 646 END_OF_TESTCASES 647 };