librespot/audio/src/decrypt.rs

59 lines
1.6 KiB
Rust
Raw Normal View History

2015-06-23 14:38:29 +00:00
use crypto::aes;
use crypto::symmetriccipher::SynchronousStreamCipher;
2017-01-29 12:50:18 +00:00
use num_bigint::BigUint;
use num_traits::FromPrimitive;
2015-06-23 14:38:29 +00:00
use std::io;
2015-06-23 17:34:48 +00:00
use std::ops::Add;
2015-06-23 14:38:29 +00:00
2017-08-03 18:58:44 +00:00
use core::audio_key::AudioKey;
2015-06-23 14:38:29 +00:00
2018-02-26 01:50:41 +00:00
const AUDIO_AESIV: &'static [u8] = &[
2018-04-25 17:29:50 +00:00
0x72, 0xe0, 0x67, 0xfb, 0xdd, 0xcb, 0xcf, 0x77, 0xeb, 0xe8, 0xbc, 0x64, 0x3f, 0x63, 0x0d, 0x93,
2018-02-26 01:50:41 +00:00
];
2015-06-23 14:38:29 +00:00
2016-01-02 15:19:39 +00:00
pub struct AudioDecrypt<T: io::Read> {
2015-06-23 14:38:29 +00:00
cipher: Box<SynchronousStreamCipher + 'static>,
key: AudioKey,
reader: T,
}
2016-01-02 15:19:39 +00:00
impl<T: io::Read> AudioDecrypt<T> {
2015-06-23 17:34:48 +00:00
pub fn new(key: AudioKey, reader: T) -> AudioDecrypt<T> {
2017-01-18 20:39:46 +00:00
let cipher = aes::ctr(aes::KeySize::KeySize128, &key.0, AUDIO_AESIV);
2015-06-23 14:38:29 +00:00
AudioDecrypt {
cipher: cipher,
key: key,
reader: reader,
}
}
}
2016-01-02 15:19:39 +00:00
impl<T: io::Read> io::Read for AudioDecrypt<T> {
2015-06-23 14:38:29 +00:00
fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
let mut buffer = vec![0u8; output.len()];
let len = try!(self.reader.read(&mut buffer));
self.cipher.process(&buffer[..len], &mut output[..len]);
Ok(len)
}
}
2016-01-02 15:19:39 +00:00
impl<T: io::Read + io::Seek> io::Seek for AudioDecrypt<T> {
2015-06-23 17:34:48 +00:00
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
let newpos = try!(self.reader.seek(pos));
let skip = newpos % 16;
let iv = BigUint::from_bytes_be(AUDIO_AESIV)
2018-02-26 01:50:41 +00:00
.add(BigUint::from_u64(newpos / 16).unwrap())
.to_bytes_be();
2017-01-18 20:39:46 +00:00
self.cipher = aes::ctr(aes::KeySize::KeySize128, &self.key.0, &iv);
2015-06-23 17:34:48 +00:00
let buf = vec![0u8; skip as usize];
let mut buf2 = vec![0u8; skip as usize];
self.cipher.process(&buf, &mut buf2);
Ok(newpos as u64)
2015-06-23 14:38:29 +00:00
}
}