1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
use std::io; use aes_ctr::stream_cipher::generic_array::GenericArray; use aes_ctr::stream_cipher::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek}; use aes_ctr::Aes128Ctr; use librespot_core::audio_key::AudioKey; const AUDIO_AESIV: [u8; 16] = [ 0x72, 0xe0, 0x67, 0xfb, 0xdd, 0xcb, 0xcf, 0x77, 0xeb, 0xe8, 0xbc, 0x64, 0x3f, 0x63, 0x0d, 0x93, ]; pub struct AudioDecrypt<T: io::Read> { cipher: Aes128Ctr, reader: T, } impl<T: io::Read> AudioDecrypt<T> { pub fn new(key: AudioKey, reader: T) -> AudioDecrypt<T> { let cipher = Aes128Ctr::new( &GenericArray::from_slice(&key.0), &GenericArray::from_slice(&AUDIO_AESIV), ); AudioDecrypt { cipher, reader } } } impl<T: io::Read> io::Read for AudioDecrypt<T> { fn read(&mut self, output: &mut [u8]) -> io::Result<usize> { let len = self.reader.read(output)?; self.cipher.apply_keystream(&mut output[..len]); Ok(len) } } impl<T: io::Read + io::Seek> io::Seek for AudioDecrypt<T> { fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> { let newpos = self.reader.seek(pos)?; self.cipher.seek(newpos); Ok(newpos) } }