浏览代码

no more clicks on SPDIF & CSpot

Philippe G 3 年之前
父节点
当前提交
60584ae207

+ 1 - 1
components/spotify/cspot/bell/include/CryptoMbedTLS.h

@@ -56,7 +56,7 @@ public:
     std::vector<uint8_t> sha1HMAC(const std::vector<uint8_t>& inputKey, const std::vector<uint8_t>& message);
 
     // 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
     void aesECBdecrypt(const std::vector<uint8_t>& key, std::vector<uint8_t>& data);

+ 1 - 1
components/spotify/cspot/bell/include/CryptoOpenSSL.h

@@ -63,7 +63,7 @@ public:
     std::vector<uint8_t> sha1HMAC(const std::vector<uint8_t>& inputKey, const std::vector<uint8_t>& message);
 
     // 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
     void aesECBdecrypt(const std::vector<uint8_t>& key, std::vector<uint8_t>& data);

+ 5 - 5
components/spotify/cspot/bell/src/CryptoMBedTLS.cpp

@@ -88,7 +88,7 @@ std::vector<uint8_t> CryptoMbedTLS::sha1HMAC(const std::vector<uint8_t> &inputKe
 }
 
 // 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
     size_t off = 0;
@@ -99,12 +99,12 @@ void CryptoMbedTLS::aesCTRXcrypt(const std::vector<uint8_t> &key, std::vector<ui
 
     // Perform decrypt
     mbedtls_aes_crypt_ctr(&aesCtx,
-                          data.size(),
+                          nbytes,
                           &off,
                           iv.data(),
                           streamBlock,
-                          data.data(),
-                          data.data());
+                          buffer,
+                          buffer);
 }
 
 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
     for (unsigned int x = 0; x < data.size() / 16; x++)
     {
-        // Perform decrypt
+        // Perform finalize
         mbedtls_aes_crypt_ecb(&aesCtx,
                               MBEDTLS_AES_DECRYPT,
                               data.data() + (x * 16),

+ 4 - 4
components/spotify/cspot/bell/src/CryptoOpenSSL.cpp

@@ -99,7 +99,7 @@ std::vector<uint8_t> CryptoOpenSSL::sha1HMAC(const std::vector<uint8_t>& inputKe
 }
 
 // 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
     auto cryptoKey = AES_KEY();
@@ -110,9 +110,9 @@ void CryptoOpenSSL::aesCTRXcrypt(const std::vector<uint8_t>& key, std::vector<ui
     unsigned int offsetInBlock = 0;
 
     CRYPTO_ctr128_encrypt(
-        data.data(),
-        data.data(),
-        data.size(),
+            buffer,
+            buffer,
+        nbytes,
         &cryptoKey,
         iv.data(),
         ecountBuf,

+ 1 - 1
components/spotify/cspot/bell/src/HTTPClient.cpp

@@ -287,7 +287,7 @@ std::string HTTPClient::HTTPResponse::readToString() {
 		return result;
 	}
 	std::string result;
-	char buffer[BUF_SIZE];
+        char buffer[BUF_SIZE+1]; // make space for null-terminator
 	size_t len;
 	do {
 		len = this->read(buffer, BUF_SIZE);

+ 18 - 8
components/spotify/cspot/include/AudioChunk.h

@@ -14,12 +14,15 @@ class AudioChunk {
 private:
     /**
      * @brief Calculates a correct IV by performing bignum addition.
-     * 
+     *
      * @param num Number to add to IV.
-     * @return std::vector<uint8_t> 
+     * @return std::vector<uint8_t>
      */
     std::vector<uint8_t> getIVSum(uint32_t num);
 
+    size_t decryptedCount = 0;
+    size_t oldStartPos;
+
 public:
     std::unique_ptr<Crypto> crypto;
     std::vector<uint8_t> decryptedData;
@@ -41,14 +44,21 @@ public:
     std::unique_ptr<WrappedSemaphore> isLoadedSemaphore;
 
     /**
-     * @brief 
+     * @brief
      */
     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.
-     * 
+     *
      * @param seqId Sequence id of requested chunk
      * @param audioKey Audio key used for decryption of audio data
      * @param startPosition Start position of current chunk in audio file
@@ -59,16 +69,16 @@ public:
 
     /**
      * @brief Appends incoming chunked data to local cache.
-     * 
+     *
      * @param data encrypted binary audio 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

+ 1 - 1
components/spotify/cspot/include/Shannon.h

@@ -13,7 +13,7 @@ public:
     void stream(std::vector<uint8_t> &buf);  /* stream cipher */
     void maconly(std::vector<uint8_t> &buf); /* accumulate 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 */
 
 private:

+ 20 - 5
components/spotify/cspot/src/AudioChunk.cpp

@@ -24,13 +24,28 @@ void AudioChunk::appendData(const std::vector<uint8_t> &data)
     this->decryptedData.insert(this->decryptedData.end(), data.begin(), data.end());
 }
 
-void AudioChunk::decrypt()
-{
-    // calculate the IV for right position
-    auto calculatedIV = this->getIVSum(startPosition / 16);
+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);
 
-    crypto->aesCTRXcrypt(this->audioKey, calculatedIV, decryptedData);
+}
 
+void AudioChunk::finalize()
+{
+    this->oldStartPos = this->startPosition;
     this->startPosition = this->endPosition - this->decryptedData.size();
     this->isLoaded = true;
 }

+ 3 - 3
components/spotify/cspot/src/AudioChunkManager.cpp

@@ -80,7 +80,7 @@ void AudioChunkManager::runTask() {
 
                         switch (data.size()) {
                         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));
                             // Got file size!
                             chunk->headerFileSize =
@@ -92,9 +92,9 @@ void AudioChunkManager::runTask() {
                             if (chunk->endPosition > chunk->headerFileSize) {
                                 chunk->endPosition = chunk->headerFileSize;
                             }
-                            CSPOT_LOG(debug, "ID: %d: Starting decrypt!",
+                            CSPOT_LOG(debug, "ID: %d: finalize chunk!",
                                       seqId);
-                            chunk->decrypt();
+                                chunk->finalize();
                             chunk->isLoadedSemaphore->give();
                             break;
 

+ 1 - 3
components/spotify/cspot/src/ChunkedByteStream.cpp

@@ -113,9 +113,7 @@ size_t ChunkedByteStream::attemptRead(uint8_t *buffer, size_t bytes, std::shared
         toRead = chunk->decryptedData.size() - offset;
     }
 
-    // Copy data
-    memcpy(buffer, chunk->decryptedData.data() + offset, toRead);
-
+    chunk->readData(buffer, offset, toRead);
     return toRead;
 }
 

+ 1 - 1
components/spotify/cspot/src/LoginBlob.cpp

@@ -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);
-    crypto->aesCTRXcrypt(encryptionKey, iv, encrypted);
+    crypto->aesCTRXcrypt(encryptionKey, iv, encrypted.data(), encrypted.size());
 
     return encrypted;
 }