Skip to content

Commit

Permalink
Add control stream encryption v2 support
Browse files Browse the repository at this point in the history
  • Loading branch information
cgutman committed Jan 14, 2024
1 parent b6bbb4f commit 3430ee2
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 6 deletions.
28 changes: 23 additions & 5 deletions src/ControlStream.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ static int intervalTotalFrameCount;
static uint64_t intervalStartTimeMs;
static int lastIntervalLossPercentage;
static int lastConnectionStatusUpdate;
static int currentEnetSequenceNumber;
static uint32_t currentEnetSequenceNumber;
static uint64_t firstFrameTimeMs;

static LINKED_BLOCKING_QUEUE invalidReferenceFrameTuples;
Expand Down Expand Up @@ -503,9 +503,18 @@ static bool encryptControlMessage(PNVCTL_ENCRYPTED_PACKET_HEADER encPacket, PNVC
unsigned char iv[16] = { 0 };
int encryptedSize = sizeof(*packet) + packet->payloadLength;

// This is a truncating cast, but it's what Nvidia does, so we have to mimic it.
// NB: Setting the IV must happen while encPacket->seq is still in native byte-order!
iv[0] = (unsigned char)encPacket->seq;
if (EncryptionFeaturesEnabled & SS_ENC_CONTROL_V2) {
// Populate the IV in little endian byte order
iv[3] = (unsigned char)(encPacket->seq >> 24);
iv[2] = (unsigned char)(encPacket->seq >> 16);
iv[1] = (unsigned char)(encPacket->seq >> 8);
iv[0] = (unsigned char)(encPacket->seq >> 0);
}
else {
// This is a truncating cast, but it's what Nvidia does, so we have to mimic it.
iv[0] = (unsigned char)encPacket->seq;
}

encPacket->encryptedHeaderType = LE16(encPacket->encryptedHeaderType);
encPacket->length = LE16(encPacket->length);
Expand Down Expand Up @@ -545,8 +554,17 @@ static bool decryptControlMessageToV1(PNVCTL_ENCRYPTED_PACKET_HEADER encPacket,
return false;
}

// This is a truncating cast, but it's what Nvidia does, so we have to mimic it.
iv[0] = (unsigned char)encPacket->seq;
if (EncryptionFeaturesEnabled & SS_ENC_CONTROL_V2) {
// Populate the IV in little endian byte order
iv[3] = (unsigned char)(encPacket->seq >> 24);
iv[2] = (unsigned char)(encPacket->seq >> 16);
iv[1] = (unsigned char)(encPacket->seq >> 8);
iv[0] = (unsigned char)(encPacket->seq >> 0);
}
else {
// This is a truncating cast, but it's what Nvidia does, so we have to mimic it.
iv[0] = (unsigned char)encPacket->seq;
}

int plaintextLength = encPacket->length - sizeof(encPacket->seq) - AES_GCM_TAG_LENGTH;
*packet = malloc(plaintextLength);
Expand Down
9 changes: 8 additions & 1 deletion src/SdpGenerator.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,18 @@ static PSDP_OPTION getAttributesList(char*urlSafeAddr) {
optionHead = NULL;
err = 0;

// Send client feature flags to Sunshine hosts
if (IS_SUNSHINE()) {
// Send client feature flags to Sunshine hosts
uint32_t moonlightFeatureFlags = ML_FF_FEC_STATUS | ML_FF_SESSION_ID_V1;
snprintf(payloadStr, sizeof(payloadStr), "%u", moonlightFeatureFlags);
err |= addAttributeString(&optionHead, "x-ml-general.featureFlags", payloadStr);

// New-style control stream encryption is low overhead, so we enable it any time it is supported
if (EncryptionFeaturesSupported & SS_ENC_CONTROL_V2) {
EncryptionFeaturesEnabled |= SS_ENC_CONTROL_V2;
}
snprintf(payloadStr, sizeof(payloadStr), "%u", EncryptionFeaturesEnabled);
err |= addAttributeString(&optionHead, "x-ss-general.encryptionEnabled", payloadStr);
}

snprintf(payloadStr, sizeof(payloadStr), "%d", StreamConfig.width);
Expand Down

0 comments on commit 3430ee2

Please sign in to comment.