Add control stream encryption v2 support

This commit is contained in:
Cameron Gutman 2024-01-14 12:58:48 -06:00
parent b6bbb4fb26
commit 3430ee2c3a
2 changed files with 31 additions and 6 deletions

View File

@ -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;
@ -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);
@ -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);

View File

@ -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);