mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-11 05:57:05 +03:00
no more clicks on SPDIF & CSpot
This commit is contained in:
@@ -56,7 +56,7 @@ public:
|
|||||||
std::vector<uint8_t> sha1HMAC(const std::vector<uint8_t>& inputKey, const std::vector<uint8_t>& message);
|
std::vector<uint8_t> sha1HMAC(const std::vector<uint8_t>& inputKey, const std::vector<uint8_t>& message);
|
||||||
|
|
||||||
// AES CTR
|
// AES CTR
|
||||||
void aesCTRXcrypt(const std::vector<uint8_t>& key, std::vector<uint8_t>& iv, std::vector<uint8_t>& data);
|
void aesCTRXcrypt(const std::vector<uint8_t>& key, std::vector<uint8_t>& iv, uint8_t* data, size_t nbytes);
|
||||||
|
|
||||||
// AES ECB
|
// AES ECB
|
||||||
void aesECBdecrypt(const std::vector<uint8_t>& key, std::vector<uint8_t>& data);
|
void aesECBdecrypt(const std::vector<uint8_t>& key, std::vector<uint8_t>& data);
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public:
|
|||||||
std::vector<uint8_t> sha1HMAC(const std::vector<uint8_t>& inputKey, const std::vector<uint8_t>& message);
|
std::vector<uint8_t> sha1HMAC(const std::vector<uint8_t>& inputKey, const std::vector<uint8_t>& message);
|
||||||
|
|
||||||
// AES CTR
|
// AES CTR
|
||||||
void aesCTRXcrypt(const std::vector<uint8_t>& key, std::vector<uint8_t>& iv, std::vector<uint8_t>& data);
|
void aesCTRXcrypt(const std::vector<uint8_t>& key, std::vector<uint8_t>& iv, uint8_t* buffer, size_t nbytes);
|
||||||
|
|
||||||
// AES ECB
|
// AES ECB
|
||||||
void aesECBdecrypt(const std::vector<uint8_t>& key, std::vector<uint8_t>& data);
|
void aesECBdecrypt(const std::vector<uint8_t>& key, std::vector<uint8_t>& data);
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ std::vector<uint8_t> CryptoMbedTLS::sha1HMAC(const std::vector<uint8_t> &inputKe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AES CTR
|
// AES CTR
|
||||||
void CryptoMbedTLS::aesCTRXcrypt(const std::vector<uint8_t> &key, std::vector<uint8_t> &iv, std::vector<uint8_t> &data)
|
void CryptoMbedTLS::aesCTRXcrypt(const std::vector<uint8_t> &key, std::vector<uint8_t> &iv, uint8_t* buffer, size_t nbytes)
|
||||||
{
|
{
|
||||||
// needed for internal cache
|
// needed for internal cache
|
||||||
size_t off = 0;
|
size_t off = 0;
|
||||||
@@ -99,12 +99,12 @@ void CryptoMbedTLS::aesCTRXcrypt(const std::vector<uint8_t> &key, std::vector<ui
|
|||||||
|
|
||||||
// Perform decrypt
|
// Perform decrypt
|
||||||
mbedtls_aes_crypt_ctr(&aesCtx,
|
mbedtls_aes_crypt_ctr(&aesCtx,
|
||||||
data.size(),
|
nbytes,
|
||||||
&off,
|
&off,
|
||||||
iv.data(),
|
iv.data(),
|
||||||
streamBlock,
|
streamBlock,
|
||||||
data.data(),
|
buffer,
|
||||||
data.data());
|
buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CryptoMbedTLS::aesECBdecrypt(const std::vector<uint8_t> &key, std::vector<uint8_t> &data)
|
void CryptoMbedTLS::aesECBdecrypt(const std::vector<uint8_t> &key, std::vector<uint8_t> &data)
|
||||||
@@ -115,7 +115,7 @@ void CryptoMbedTLS::aesECBdecrypt(const std::vector<uint8_t> &key, std::vector<u
|
|||||||
// Mbedtls's decrypt only works on 16 byte blocks
|
// Mbedtls's decrypt only works on 16 byte blocks
|
||||||
for (unsigned int x = 0; x < data.size() / 16; x++)
|
for (unsigned int x = 0; x < data.size() / 16; x++)
|
||||||
{
|
{
|
||||||
// Perform decrypt
|
// Perform finalize
|
||||||
mbedtls_aes_crypt_ecb(&aesCtx,
|
mbedtls_aes_crypt_ecb(&aesCtx,
|
||||||
MBEDTLS_AES_DECRYPT,
|
MBEDTLS_AES_DECRYPT,
|
||||||
data.data() + (x * 16),
|
data.data() + (x * 16),
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ std::vector<uint8_t> CryptoOpenSSL::sha1HMAC(const std::vector<uint8_t>& inputKe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AES CTR
|
// AES CTR
|
||||||
void CryptoOpenSSL::aesCTRXcrypt(const std::vector<uint8_t>& key, std::vector<uint8_t>& iv, std::vector<uint8_t> &data)
|
void CryptoOpenSSL::aesCTRXcrypt(const std::vector<uint8_t>& key, std::vector<uint8_t>& iv, uint8_t* buffer, size_t nbytes)
|
||||||
{
|
{
|
||||||
// Prepare AES_KEY
|
// Prepare AES_KEY
|
||||||
auto cryptoKey = AES_KEY();
|
auto cryptoKey = AES_KEY();
|
||||||
@@ -110,9 +110,9 @@ void CryptoOpenSSL::aesCTRXcrypt(const std::vector<uint8_t>& key, std::vector<ui
|
|||||||
unsigned int offsetInBlock = 0;
|
unsigned int offsetInBlock = 0;
|
||||||
|
|
||||||
CRYPTO_ctr128_encrypt(
|
CRYPTO_ctr128_encrypt(
|
||||||
data.data(),
|
buffer,
|
||||||
data.data(),
|
buffer,
|
||||||
data.size(),
|
nbytes,
|
||||||
&cryptoKey,
|
&cryptoKey,
|
||||||
iv.data(),
|
iv.data(),
|
||||||
ecountBuf,
|
ecountBuf,
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ std::string HTTPClient::HTTPResponse::readToString() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
std::string result;
|
std::string result;
|
||||||
char buffer[BUF_SIZE];
|
char buffer[BUF_SIZE+1]; // make space for null-terminator
|
||||||
size_t len;
|
size_t len;
|
||||||
do {
|
do {
|
||||||
len = this->read(buffer, BUF_SIZE);
|
len = this->read(buffer, BUF_SIZE);
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ private:
|
|||||||
*/
|
*/
|
||||||
std::vector<uint8_t> getIVSum(uint32_t num);
|
std::vector<uint8_t> getIVSum(uint32_t num);
|
||||||
|
|
||||||
|
size_t decryptedCount = 0;
|
||||||
|
size_t oldStartPos;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::unique_ptr<Crypto> crypto;
|
std::unique_ptr<Crypto> crypto;
|
||||||
std::vector<uint8_t> decryptedData;
|
std::vector<uint8_t> decryptedData;
|
||||||
@@ -45,6 +48,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
std::unique_ptr<WrappedSemaphore> isHeaderFileSizeLoadedSemaphore;
|
std::unique_ptr<WrappedSemaphore> isHeaderFileSizeLoadedSemaphore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrypts data and writes it to the target buffer
|
||||||
|
* @param target data buffer to write to
|
||||||
|
* @param offset data offset
|
||||||
|
* @param nbytes number of bytes to read
|
||||||
|
*/
|
||||||
|
void readData(uint8_t *target, size_t offset, size_t nbytes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief AudioChunk handles all audiochunk related operations.
|
* @brief AudioChunk handles all audiochunk related operations.
|
||||||
@@ -65,10 +75,10 @@ public:
|
|||||||
void appendData(const std::vector<uint8_t> &data);
|
void appendData(const std::vector<uint8_t> &data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Performs AES CTR decryption of received data.
|
* @brief Sets loaded status on the chunk
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void decrypt();
|
void finalize();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public:
|
|||||||
void stream(std::vector<uint8_t> &buf); /* stream cipher */
|
void stream(std::vector<uint8_t> &buf); /* stream cipher */
|
||||||
void maconly(std::vector<uint8_t> &buf); /* accumulate MAC */
|
void maconly(std::vector<uint8_t> &buf); /* accumulate MAC */
|
||||||
void encrypt(std::vector<uint8_t> &buf); /* encrypt + MAC */
|
void encrypt(std::vector<uint8_t> &buf); /* encrypt + MAC */
|
||||||
void decrypt(std::vector<uint8_t> &buf); /* decrypt + MAC */
|
void decrypt(std::vector<uint8_t> &buf); /* finalize + MAC */
|
||||||
void finish(std::vector<uint8_t> &buf); /* finalise MAC */
|
void finish(std::vector<uint8_t> &buf); /* finalise MAC */
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -24,13 +24,28 @@ void AudioChunk::appendData(const std::vector<uint8_t> &data)
|
|||||||
this->decryptedData.insert(this->decryptedData.end(), data.begin(), data.end());
|
this->decryptedData.insert(this->decryptedData.end(), data.begin(), data.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioChunk::decrypt()
|
void AudioChunk::readData(uint8_t *target, size_t offset, size_t nbytes) {
|
||||||
|
auto readPos = offset + nbytes;
|
||||||
|
auto modulo = (readPos % 16);
|
||||||
|
auto ivReadPos = readPos;
|
||||||
|
if (modulo != 0) {
|
||||||
|
ivReadPos += (16 - modulo);
|
||||||
|
}
|
||||||
|
if (ivReadPos > decryptedCount) {
|
||||||
|
// calculate the IV for right position
|
||||||
|
auto calculatedIV = this->getIVSum((oldStartPos + decryptedCount) / 16);
|
||||||
|
|
||||||
|
crypto->aesCTRXcrypt(this->audioKey, calculatedIV, decryptedData.data() + decryptedCount, ivReadPos - decryptedCount);
|
||||||
|
|
||||||
|
decryptedCount = ivReadPos;
|
||||||
|
}
|
||||||
|
memcpy(target, this->decryptedData.data() + offset, nbytes);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioChunk::finalize()
|
||||||
{
|
{
|
||||||
// calculate the IV for right position
|
this->oldStartPos = this->startPosition;
|
||||||
auto calculatedIV = this->getIVSum(startPosition / 16);
|
|
||||||
|
|
||||||
crypto->aesCTRXcrypt(this->audioKey, calculatedIV, decryptedData);
|
|
||||||
|
|
||||||
this->startPosition = this->endPosition - this->decryptedData.size();
|
this->startPosition = this->endPosition - this->decryptedData.size();
|
||||||
this->isLoaded = true;
|
this->isLoaded = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ void AudioChunkManager::runTask() {
|
|||||||
|
|
||||||
switch (data.size()) {
|
switch (data.size()) {
|
||||||
case DATA_SIZE_HEADER: {
|
case DATA_SIZE_HEADER: {
|
||||||
CSPOT_LOG(debug, "ID: %d: header decrypt!", seqId);
|
CSPOT_LOG(debug, "ID: %d: header finalize!", seqId);
|
||||||
auto headerSize = ntohs(extract<uint16_t>(data, 2));
|
auto headerSize = ntohs(extract<uint16_t>(data, 2));
|
||||||
// Got file size!
|
// Got file size!
|
||||||
chunk->headerFileSize =
|
chunk->headerFileSize =
|
||||||
@@ -92,9 +92,9 @@ void AudioChunkManager::runTask() {
|
|||||||
if (chunk->endPosition > chunk->headerFileSize) {
|
if (chunk->endPosition > chunk->headerFileSize) {
|
||||||
chunk->endPosition = chunk->headerFileSize;
|
chunk->endPosition = chunk->headerFileSize;
|
||||||
}
|
}
|
||||||
CSPOT_LOG(debug, "ID: %d: Starting decrypt!",
|
CSPOT_LOG(debug, "ID: %d: finalize chunk!",
|
||||||
seqId);
|
seqId);
|
||||||
chunk->decrypt();
|
chunk->finalize();
|
||||||
chunk->isLoadedSemaphore->give();
|
chunk->isLoadedSemaphore->give();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -113,9 +113,7 @@ size_t ChunkedByteStream::attemptRead(uint8_t *buffer, size_t bytes, std::shared
|
|||||||
toRead = chunk->decryptedData.size() - offset;
|
toRead = chunk->decryptedData.size() - offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy data
|
chunk->readData(buffer, offset, toRead);
|
||||||
memcpy(buffer, chunk->decryptedData.data() + offset, toRead);
|
|
||||||
|
|
||||||
return toRead;
|
return toRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ std::vector<uint8_t> LoginBlob::decodeBlob(const std::vector<uint8_t> &blob, con
|
|||||||
}
|
}
|
||||||
|
|
||||||
encryptionKey = std::vector<uint8_t>(encryptionKey.begin(), encryptionKey.begin() + 16);
|
encryptionKey = std::vector<uint8_t>(encryptionKey.begin(), encryptionKey.begin() + 16);
|
||||||
crypto->aesCTRXcrypt(encryptionKey, iv, encrypted);
|
crypto->aesCTRXcrypt(encryptionKey, iv, encrypted.data(), encrypted.size());
|
||||||
|
|
||||||
return encrypted;
|
return encrypted;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user