This commit is contained in:
DDVTech 2021-09-10 23:44:31 +02:00 committed by Thulinma
parent 5b79f296d6
commit fccf66fba2
280 changed files with 56975 additions and 71885 deletions

View file

@ -1,38 +1,35 @@
#include "encryption.h"
#include "auth.h"
#include "bitfields.h"
#include "defines.h"
#include "encode.h"
#include "encryption.h"
#include "http_parser.h"
#include "nal.h" /*LTS*/
#include "rijndael.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <cstdio>
#include <iostream>
#include "rijndael.h"
#include "defines.h"
#include "bitfields.h"
#include "http_parser.h"
#include "encode.h"
#include "nal.h"/*LTS*/
#include <sstream>
namespace Encryption {
///helper function for printing binary values
std::string hexString(const char * data, unsigned long dataLen){
namespace Encryption{
/// helper function for printing binary values
std::string hexString(const char *data, unsigned long dataLen){
std::stringstream res;
for (int i = 0; i < dataLen; i++){
res << std::hex << std::setw(2) << std::setfill('0') << (int)data[i];
if (i % 4 == 3){
res << " ";
}
if (i % 4 == 3){res << " ";}
}
return res.str();
}
std::string AES_Crypt(const std::string & data, const std::string & key, std::string & ivec) {
std::string AES_Crypt(const std::string &data, const std::string &key, std::string &ivec){
return AES_Crypt(data.data(), data.size(), key.data(), ivec.data());
}
std::string AES_Crypt(const char * data, int dataLen, const char * key, const char * ivec) {
char * outData = (char *)malloc(dataLen * sizeof(char));
std::string AES_Crypt(const char *data, int dataLen, const char *key, const char *ivec){
char *outData = (char *)malloc(dataLen * sizeof(char));
memcpy(outData, data, dataLen);
AESFullCrypt(outData, dataLen, key, ivec);
std::string result = std::string(outData, dataLen);
@ -40,51 +37,52 @@ namespace Encryption {
return result;
}
///This function encrypts data in-place.
///It alters all parameters except dataLen.
///Do not use it unless you know what you are doing.
void AESPartialCrypt(char * data, int dataLen, char * expandedKey, char * eCount, char * iVec, unsigned int & num, bool & initialize) {
if (initialize) {
/// This function encrypts data in-place.
/// It alters all parameters except dataLen.
/// Do not use it unless you know what you are doing.
void AESPartialCrypt(char *data, int dataLen, char *expandedKey, char *eCount, char *iVec,
unsigned int &num, bool &initialize){
if (initialize){
num = 0;
memset(eCount, 0, 16);
///Before use, make sure the iVec is in the UPPER 8 bytes
/// Before use, make sure the iVec is in the UPPER 8 bytes
memset(iVec + 8, 0, 8);
///Before use, make sure this is not the only copy of the key you had. It is lost upon initialization
/// Before use, make sure this is not the only copy of the key you had. It is lost upon initialization
char cryptKey[224];
AES_set_encrypt_key(expandedKey, 128, cryptKey);
memcpy(expandedKey, cryptKey, 224);
initialize = false;
}
char * outData = (char *)malloc(dataLen * sizeof(char));
char *outData = (char *)malloc(dataLen * sizeof(char));
AES_CTR128_crypt(data, outData, dataLen, expandedKey, iVec, eCount, num);
memcpy(data, outData, dataLen);
free(outData);
}
//Generates the contentkey from a keyseed and a keyid
std::string PR_GenerateContentKey(std::string & keyseed, std::string & keyid) {
// Generates the contentkey from a keyseed and a keyid
std::string PR_GenerateContentKey(std::string &keyseed, std::string &keyid){
char contentKey[16];
char dataBlob[92];
char keyA[32], keyB[32], keyC[32];
std::string keyidBytes = PR_GuidToByteArray(keyid);
memcpy(dataBlob, keyseed.data(), 30);
memcpy(dataBlob, keyseed.data(), 30);
memcpy(dataBlob + 30, keyidBytes.data(), 16);
memcpy(dataBlob + 46, keyseed.data(), 30);
memcpy(dataBlob + 76, keyidBytes.data(), 16);
//KeyA is generated from keyseed/keyid
// KeyA is generated from keyseed/keyid
Secure::sha256bin(dataBlob, 46, keyA);
//KeyB is generated from keyseed/keyid/keyseed
// KeyB is generated from keyseed/keyid/keyseed
Secure::sha256bin(dataBlob, 76, keyB);
//KeyC is generated from keyseed/keyid/keyseed/keyid
// KeyC is generated from keyseed/keyid/keyseed/keyid
Secure::sha256bin(dataBlob, 92, keyC);
for (int i = 0; i < 16; i++) {
for (int i = 0; i < 16; i++){
contentKey[i] = keyA[i] ^ keyA[i + 16] ^ keyB[i] ^ keyB[i + 16] ^ keyC[i] ^ keyC[i + 16];
}
return std::string(contentKey, 16);
}
//Transforms a guid to the MS byte array representation
std::string PR_GuidToByteArray(std::string & guid) {
// Transforms a guid to the MS byte array representation
std::string PR_GuidToByteArray(std::string &guid){
char result[16];
result[0] = guid[3];
result[1] = guid[2];
@ -100,9 +98,8 @@ namespace Encryption {
return std::string(result, 8);
}
///This function encrypts data in-place.
void AESFullCrypt(char * data, int dataLen, const char * key, const char * ivec) {
/// This function encrypts data in-place.
void AESFullCrypt(char *data, int dataLen, const char *key, const char *ivec){
unsigned int num = 0;
char expandedKey[224];
memcpy(expandedKey, key, 16);
@ -113,12 +110,12 @@ namespace Encryption {
AESPartialCrypt(data, dataLen, expandedKey, eCount, iVec, num, initialize);
}
void encryptPlayReady(DTSC::Packet & thisPack, std::string & codec, const char * iVec, const char * key) {
char * data;
void encryptPlayReady(DTSC::Packet &thisPack, std::string &codec, const char *iVec, const char *key){
char *data;
size_t dataLen;
thisPack.getString("data", data, dataLen);
if (codec == "H264") {
if (codec == "H264"){
unsigned int num = 0;
char expandedKey[224];
memcpy(expandedKey, key, 16);
@ -130,33 +127,30 @@ namespace Encryption {
int pos = 0;
std::deque<int> nalSizes = nalu::parseNalSizes(thisPack);
for (std::deque<int>::iterator it = nalSizes.begin(); it != nalSizes.end(); it++) {
int encrypted = (*it - 5) & ~0xF;//Bitmask to a multiple of 16
for (std::deque<int>::iterator it = nalSizes.begin(); it != nalSizes.end(); it++){
int encrypted = (*it - 5) & ~0xF; // Bitmask to a multiple of 16
int clear = *it - encrypted;
Encryption::AESPartialCrypt(data + pos + clear, encrypted, expandedKey, eCount, initVec, num, initialize);
pos += *it;
}
}
if (codec == "AAC") {
Encryption::AESFullCrypt(data, dataLen, key, iVec);
}
if (codec == "AAC"){Encryption::AESFullCrypt(data, dataLen, key, iVec);}
}
/// Converts a hexidecimal string format key to binary string format.
std::string binKey(std::string hexkey) {
std::string binKey(std::string hexkey){
char newkey[16];
memset(newkey, 0, 16);
for (size_t i = 0; i < hexkey.size(); ++i) {
for (size_t i = 0; i < hexkey.size(); ++i){
char c = hexkey[i];
newkey[i >> 1] |= ((c & 15) + (((c & 64) >> 6) | ((c & 64) >> 3))) << ((~i & 1) << 2);
}
return std::string(newkey, 16);
}
/// Helper function for urlescape.
/// Encodes a character as two hex digits.
std::string hex(char dec) {
std::string hex(char dec){
char dig1 = (dec & 0xF0) >> 4;
char dig2 = (dec & 0x0F);
if (dig1 <= 9) dig1 += 48;
@ -168,20 +162,19 @@ namespace Encryption {
r.append(&dig2, 1);
return r;
}
std::string hex(const std::string & input) {
std::string hex(const std::string &input){
std::string res;
res.reserve(input.size() * 2);
for (unsigned int i = 0; i < input.size(); i++) {
res += hex(input[i]);
}
for (unsigned int i = 0; i < input.size(); i++){res += hex(input[i]);}
return res;
}
void fillVerimatrix(verimatrixData & vmData) {
void fillVerimatrix(verimatrixData &vmData){
int hostPos = vmData.url.find("://") + 3;
int portPos = vmData.url.find(":", hostPos);
std::string hostName = vmData.url.substr(hostPos, (portPos == std::string::npos ? portPos : portPos - hostPos));
std::string hostName =
vmData.url.substr(hostPos, (portPos == std::string::npos ? portPos : portPos - hostPos));
int port = (portPos == std::string::npos ? 80 : atoi(vmData.url.data() + portPos + 1));
Socket::Connection veriConn(hostName, port, true);
@ -190,44 +183,43 @@ namespace Encryption {
H.SetHeader("Host", vmData.url.substr(hostPos));
H.SendRequest(veriConn);
H.Clean();
while (veriConn && (!veriConn.spool() || !H.Read(veriConn))) {}
while (veriConn && (!veriConn.spool() || !H.Read(veriConn))){}
vmData.key = binKey(H.GetHeader("Key"));
vmData.keyid = H.GetHeader("KeyId");
vmData.laurl = H.GetHeader("LAURL");
vmData.lauurl = H.GetHeader("LAUURL");
}
void verimatrixData::read(const char * shmPage) {
void verimatrixData::read(const char *shmPage){
int offset = 0;
url = std::string(shmPage + offset);
offset += url.size() + 1;//+1 for the concluding 0-byte
offset += url.size() + 1; //+1 for the concluding 0-byte
name = std::string(shmPage + offset);
offset += name.size() + 1;//+1 for the concluding 0-byte
offset += name.size() + 1; //+1 for the concluding 0-byte
key = std::string(shmPage + offset);
offset += key.size() + 1;//+1 for the concluding 0-byte
offset += key.size() + 1; //+1 for the concluding 0-byte
keyid = std::string(shmPage + offset);
offset += keyid.size() + 1;//+1 for the concluding 0-byte
offset += keyid.size() + 1; //+1 for the concluding 0-byte
laurl = std::string(shmPage + offset);
offset += laurl.size() + 1;//+1 for the concluding 0-byte
offset += laurl.size() + 1; //+1 for the concluding 0-byte
lauurl = std::string(shmPage + offset);
key = binKey(key);
}
void verimatrixData::write(char * shmPage) {
void verimatrixData::write(char *shmPage){
int offset = 0;
memcpy(shmPage + offset, url.c_str(), url.size() + 1);
offset += url.size() + 1;//+1 for the concluding 0-byte
offset += url.size() + 1; //+1 for the concluding 0-byte
memcpy(shmPage + offset, name.c_str(), name.size() + 1);
offset += name.size() + 1;//+1 for the concluding 0-byte
offset += name.size() + 1; //+1 for the concluding 0-byte
std::string tmpKey = hex(key);
memcpy(shmPage + offset, tmpKey.c_str(), tmpKey.size() + 1);
offset += tmpKey.size() + 1;//+1 for the concluding 0-byte
offset += tmpKey.size() + 1; //+1 for the concluding 0-byte
memcpy(shmPage + offset, keyid.c_str(), keyid.size() + 1);
offset += keyid.size() + 1;//+1 for the concluding 0-byte
offset += keyid.size() + 1; //+1 for the concluding 0-byte
memcpy(shmPage + offset, laurl.c_str(), laurl.size() + 1);
offset += laurl.size() + 1;//+1 for the concluding 0-byte
offset += laurl.size() + 1; //+1 for the concluding 0-byte
memcpy(shmPage + offset, lauurl.c_str(), lauurl.size() + 1);
}
}
}// namespace Encryption