MCPcopy Create free account
hub / github.com/ClassicOldSong/Apollo / encode_control

Function encode_control

src/stream.cpp:435–483  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

433 */
434 template<std::size_t max_payload_size>
435 static inline std::string_view encode_control(session_t *session, const std::string_view &plaintext, std::array<std::uint8_t, max_payload_size> &tagged_cipher) {
436 static_assert(
437 max_payload_size >= sizeof(control_encrypted_t) + sizeof(crypto::cipher::tag_size),
438 "max_payload_size >= sizeof(control_encrypted_t) + sizeof(crypto::cipher::tag_size)"
439 );
440
441 if (session->config.controlProtocolType != 13) {
442 return plaintext;
443 }
444
445 auto seq = session->control.seq++;
446
447 auto &iv = session->control.outgoing_iv;
448 if (session->config.encryptionFlagsEnabled & SS_ENC_CONTROL_V2) {
449 // We use the deterministic IV construction algorithm specified in NIST SP 800-38D
450 // Section 8.2.1. The sequence number is our "invocation" field and the 'CH' in the
451 // high bytes is the "fixed" field. Because each client provides their own unique
452 // key, our values in the fixed field need only uniquely identify each independent
453 // use of the client's key with AES-GCM in our code.
454 //
455 // The sequence number is 32 bits long which allows for 2^32 control stream messages
456 // to be sent to each client before the IV repeats.
457 iv.resize(12);
458 std::copy_n((uint8_t *) &seq, sizeof(seq), std::begin(iv));
459 iv[10] = 'H'; // Host originated
460 iv[11] = 'C'; // Control stream
461 } else {
462 // Nvidia's old style encryption uses a 16-byte IV
463 iv.resize(16);
464
465 iv[0] = (std::uint8_t) seq;
466 }
467
468 auto packet = (control_encrypted_p) tagged_cipher.data();
469
470 auto bytes = session->control.cipher.encrypt(plaintext, packet->payload(), &iv);
471 if (bytes <= 0) {
472 BOOST_LOG(error) << "Couldn't encrypt control data"sv;
473 return {};
474 }
475
476 std::uint16_t packet_length = bytes + crypto::cipher::tag_size + sizeof(control_encrypted_t::seq);
477
478 packet->encryptedHeaderType = util::endian::little(0x0001);
479 packet->length = util::endian::little(packet_length);
480 packet->seq = util::endian::little(seq);
481
482 return std::string_view {(char *) tagged_cipher.data(), packet_length + sizeof(control_encrypted_t) - sizeof(control_encrypted_t::seq)};
483 }
484
485 int start_broadcast(broadcast_ctx_t &ctx);
486 void end_broadcast(broadcast_ctx_t &ctx);

Callers 4

send_feedback_msgFunction · 0.85
send_hdr_modeFunction · 0.85
controlBroadcastThreadFunction · 0.85
graceful_stopFunction · 0.85

Calls 4

littleFunction · 0.85
encryptMethod · 0.80
dataMethod · 0.45
payloadMethod · 0.45

Tested by

no test coverage detected