idf overriding method to bring back SPDIF and fix SPI + new CSPOT (which crashes)

This commit is contained in:
Philippe G
2022-01-04 00:15:33 -08:00
parent cf1315e6a4
commit 06b637c55b
43 changed files with 2955 additions and 402 deletions

View File

@@ -6,11 +6,24 @@ using random_bytes_engine = std::independent_bits_engine<std::default_random_eng
Session::Session()
{
this->clientHello = ClientHello_init_default;
this->apResponse = APResponseMessage_init_default;
this->authRequest = ClientResponseEncrypted_init_default;
this->clientResPlaintext = ClientResponsePlaintext_init_default;
// Generates the public and priv key
this->crypto = std::make_unique<Crypto>();
this->shanConn = std::make_shared<ShannonConnection>();
}
Session::~Session()
{
pbFree(ClientHello_fields, &clientHello);
pbFree(APResponseMessage_fields, &apResponse);
pbFree(ClientResponseEncrypted_fields, &authRequest);
pbFree(ClientResponsePlaintext_fields, &clientResPlaintext);
}
void Session::connect(std::unique_ptr<PlainConnection> connection)
{
this->conn = std::move(connection);
@@ -37,16 +50,16 @@ std::vector<uint8_t> Session::authenticate(std::shared_ptr<LoginBlob> blob)
authBlob = blob;
// prepare authentication request proto
authRequest.login_credentials.username = blob->username;
authRequest.login_credentials.auth_data = blob->authData;
authRequest.login_credentials.typ = static_cast<AuthenticationType>(blob->authType);
authRequest.system_info.cpu_family = CpuFamily::CPU_UNKNOWN;
authRequest.system_info.os = Os::OS_UNKNOWN;
authRequest.system_info.system_information_string = std::string(informationString);
authRequest.system_info.device_id = std::string(deviceId);
authRequest.version_string = std::string(versionString);
authRequest.login_credentials.username = (char *)(blob->username.c_str());
authRequest.login_credentials.auth_data = vectorToPbArray(blob->authData);
authRequest.login_credentials.typ = (AuthenticationType) blob->authType;
authRequest.system_info.cpu_family = CpuFamily_CPU_UNKNOWN;
authRequest.system_info.os = Os_OS_UNKNOWN;
authRequest.system_info.system_information_string = (char *)informationString;
authRequest.system_info.device_id = (char *)deviceId;
authRequest.version_string = (char *)versionString;
auto data = encodePb(authRequest);
auto data = pbEncode(ClientResponseEncrypted_fields, &authRequest);
// Send login request
this->shanConn->sendPacket(LOGIN_REQUEST_COMMAND, data);
@@ -82,11 +95,11 @@ void Session::processAPHelloResponse(std::vector<uint8_t> &helloPacket)
CSPOT_LOG(debug, "Received AP hello response");
// Decode the response
auto skipSize = std::vector<uint8_t>(data.begin() + 4, data.end());
apResponse = decodePb<APResponseMessage>(skipSize);
pbDecode(apResponse, APResponseMessage_fields, skipSize);
auto kkEy = apResponse.challenge->login_crypto_challenge.diffie_hellman->gs;
auto diffieKey = std::vector<uint8_t>(apResponse.challenge.login_crypto_challenge.diffie_hellman.gs, apResponse.challenge.login_crypto_challenge.diffie_hellman.gs + 96);
// Compute the diffie hellman shared key based on the response
auto sharedKey = this->crypto->dhCalculateShared(kkEy);
auto sharedKey = this->crypto->dhCalculateShared(diffieKey);
// Init client packet + Init server packets are required for the hmac challenge
data.insert(data.begin(), helloPacket.begin(), helloPacket.end());
@@ -106,11 +119,14 @@ void Session::processAPHelloResponse(std::vector<uint8_t> &helloPacket)
auto lastVec = std::vector<uint8_t>(resultData.begin(), resultData.begin() + 0x14);
// Digest generated!
clientResPlaintext.login_crypto_response = {};
clientResPlaintext.login_crypto_response.diffie_hellman.emplace();
clientResPlaintext.login_crypto_response.diffie_hellman->hmac = crypto->sha1HMAC(lastVec, data);
auto digest = crypto->sha1HMAC(lastVec, data);
clientResPlaintext.login_crypto_response.has_diffie_hellman = true;
auto resultPacket = encodePb(clientResPlaintext);
std::copy(digest.begin(),
digest.end(),
clientResPlaintext.login_crypto_response.diffie_hellman.hmac);
auto resultPacket = pbEncode(ClientResponsePlaintext_fields, &clientResPlaintext);
auto emptyPrefix = std::vector<uint8_t>(0);
@@ -136,20 +152,27 @@ std::vector<uint8_t> Session::sendClientHelloRequest()
this->crypto->dhInit();
// Copy the public key into diffiehellman hello packet
clientHello.login_crypto_hello.diffie_hellman.emplace();
clientHello.feature_set.emplace();
clientHello.login_crypto_hello.diffie_hellman->gc = this->crypto->publicKey;
clientHello.login_crypto_hello.diffie_hellman->server_keys_known = 1;
clientHello.build_info.product = Product::PRODUCT_PARTNER;
clientHello.build_info.platform = Platform::PLATFORM_LINUX_X86;
clientHello.build_info.version = 112800721;
clientHello.feature_set->autoupdate2 = true;
clientHello.cryptosuites_supported = std::vector<Cryptosuite>({Cryptosuite::CRYPTO_SUITE_SHANNON});
clientHello.padding = std::vector<uint8_t>({0x1E});
std::copy(this->crypto->publicKey.begin(),
this->crypto->publicKey.end(),
clientHello.login_crypto_hello.diffie_hellman.gc);
clientHello.login_crypto_hello.diffie_hellman.server_keys_known = 1;
clientHello.build_info.product = Product_PRODUCT_PARTNER;
clientHello.build_info.platform = Platform2_PLATFORM_LINUX_X86;
clientHello.build_info.version = SPOTIFY_VERSION;
clientHello.feature_set.autoupdate2 = true;
clientHello.cryptosuites_supported[0] = Cryptosuite_CRYPTO_SUITE_SHANNON;
clientHello.padding[0] = 0x1E;
clientHello.has_feature_set = true;
clientHello.login_crypto_hello.has_diffie_hellman = true;
clientHello.has_padding = true;
clientHello.has_feature_set = true;
// Generate the random nonce
clientHello.client_nonce = crypto->generateVectorWithRandomData(16);
auto vecData = encodePb(clientHello);
auto nonce = crypto->generateVectorWithRandomData(16);
std::copy(nonce.begin(), nonce.end(), clientHello.client_nonce);
auto vecData = pbEncode(ClientHello_fields, &clientHello);
auto prefix = std::vector<uint8_t>({0x00, 0x04});
return this->conn->sendPrefixPacket(prefix, vecData);
}