[FFmpeg-cvslog] Add support for playing Audible AAXC (.aaxc) files [PATCH v4]
Vesselin Bontchev
git at videolan.org
Thu Nov 5 18:14:22 EET 2020
ffmpeg | branch: master | Vesselin Bontchev <vesselin.bontchev at yandex.com> | Sat Jan 1 09:00:00 2000 +0000| [03fb314acfa4f5a4af84a6fc82a425477fd352eb] | committer: Vesselin Bontchev
Add support for playing Audible AAXC (.aaxc) files [PATCH v4]
The AAXC container format is the same as the (already supported) Audible
AAX format but it uses a different encryption scheme.
Note: audible_key and audible_iv values are variable (per file) and are
externally fed.
It is possible to extend https://github.com/mkb79/Audible to derive the
audible_key and audible_key values.
Relevant code:
def decrypt_voucher(deviceSerialNumber, customerId, deviceType, asin, voucher):
buf = (deviceType + deviceSerialNumber + customerId + asin).encode("ascii")
digest = hashlib.sha256(buf).digest()
key = digest[0:16]
iv = digest[16:]
# decrypt "voucher" using AES in CBC mode with no padding
cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = cipher.decrypt(voucher).rstrip(b"\x00") # improve this!
return json.loads(plaintext)
The decrypted "voucher" has the required audible_key and audible_iv
values.
Update (Nov-2020): This patch has now been tested by multiple folks -
details at the following URL:
https://github.com/mkb79/Audible/issues/3
Signed-off-by: Vesselin Bontchev <vesselin.bontchev at yandex.com>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=03fb314acfa4f5a4af84a6fc82a425477fd352eb
---
libavformat/isom.h | 4 ++++
libavformat/mov.c | 33 +++++++++++++++++++++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/libavformat/isom.h b/libavformat/isom.h
index 78495fd336..5a6d504090 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -286,6 +286,10 @@ typedef struct MOVContext {
int activation_bytes_size;
void *audible_fixed_key;
int audible_fixed_key_size;
+ void *audible_key;
+ int audible_key_size;
+ void *audible_iv;
+ int audible_iv_size;
struct AVAES *aes_decrypt;
uint8_t *decryption_key;
int decryption_key_len;
diff --git a/libavformat/mov.c b/libavformat/mov.c
index dd0db6bca7..2b90e31170 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1075,6 +1075,30 @@ fail:
return ret;
}
+static int mov_aaxc_crypto(MOVContext *c)
+{
+ if (c->audible_key_size != 16) {
+ av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_key value needs to be 16 bytes!\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (c->audible_iv_size != 16) {
+ av_log(c->fc, AV_LOG_FATAL, "[aaxc] audible_iv value needs to be 16 bytes!\n");
+ return AVERROR(EINVAL);
+ }
+
+ c->aes_decrypt = av_aes_alloc();
+ if (!c->aes_decrypt) {
+ return AVERROR(ENOMEM);
+ }
+
+ memcpy(c->file_key, c->audible_key, 16);
+ memcpy(c->file_iv, c->audible_iv, 16);
+ c->aax_mode = 1;
+
+ return 0;
+}
+
// Audible AAX (and AAX+) bytestream decryption
static int aax_filter(uint8_t *input, int size, MOVContext *c)
{
@@ -1123,6 +1147,11 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
av_dict_set(&c->fc->metadata, "compatible_brands",
comp_brands_str, AV_DICT_DONT_STRDUP_VAL);
+ // Logic for handling Audible's .aaxc files
+ if (!strcmp(type, "aaxc")) {
+ mov_aaxc_crypto(c);
+ }
+
return 0;
}
@@ -8170,6 +8199,10 @@ static const AVOption mov_options[] = {
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = FLAGS },
{ "activation_bytes", "Secret bytes for Audible AAX files", OFFSET(activation_bytes),
AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
+ { "audible_key", "AES-128 Key for Audible AAXC files", OFFSET(audible_key),
+ AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
+ { "audible_iv", "AES-128 IV for Audible AAXC files", OFFSET(audible_iv),
+ AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
{ "audible_fixed_key", // extracted from libAAX_SDK.so and AAXSDKWin.dll files!
"Fixed key used for handling Audible AAX files", OFFSET(audible_fixed_key),
AV_OPT_TYPE_BINARY, {.str="77214d4b196a87cd520045fd20a51d67"},
More information about the ffmpeg-cvslog
mailing list