iOS 8 and 9 decryption now works; need to test AAC audio decompression.

This commit is contained in:
fduncanh
2021-12-18 17:34:11 -05:00
parent b0c8336960
commit a8657e497b
7 changed files with 70 additions and 42 deletions

View File

@@ -5,12 +5,15 @@
#define GLOBAL_MODEL "AppleTV2,1"
#define GLOBAL_VERSION "220.68"
/* use old protocol for AES key if User-Agent string is contained in these strings */
/* replace xxx by any new User-Agent string as needed */
#define OLD_PROTOCOL_AUDIO_CLIENT_LIST "AirMyPC/2.0;xxx"
#define OLD_PROTOCOL_VIDEO_CLIENT_LIST "AirMyPC/2.0;xxx"
/* use old protocol (unhashed AESkey for audio decryption if clients source version is not greater than 330.x.x */
#define OLD_PROTOCOL_AUDIO_CLIENT_SOURCEVERSION "330.0.0"
#define DECRYPTION_TEST 0
/* use old protocol for audio or video AES key if client's User-Agent string is contained in these strings */
/* replace xxx by any new User-Agent string as needed */
#define OLD_PROTOCOL_AUDIO_CLIENT_USER_AGENT_LIST "AirMyPC/2.0;xxx"
#define OLD_PROTOCOL_VIDEO_CLIENT_USER_AGENT_LIST "AirMyPC/2.0;xxx"
#define DECRYPTION_TEST 2
#define MAX_HWADDR_LEN 6

View File

@@ -152,8 +152,8 @@ raop_buffer_decrypt(raop_buffer_t *raop_buffer, unsigned char *data, unsigned ch
#endif
if (DECRYPTION_TEST) {
printf("%s\n", OLD_PROTOCOL_AUDIO_CLIENT_LIST);
printf("%d before %s", payload_size, utils_data_to_string(&data[12],16,16 ));
printf("encrypted header %s", utils_data_to_string(data,12,12));
if (payload_size) printf("%d before %s", payload_size, utils_data_to_string(&data[12],16,16 ));
}
encryptedlen = payload_size / 16*16;
memset(output, 0, payload_size);
@@ -164,9 +164,17 @@ raop_buffer_decrypt(raop_buffer_t *raop_buffer, unsigned char *data, unsigned ch
memcpy(output + encryptedlen, &data[12 + encryptedlen], payload_size - encryptedlen);
*outputlen = payload_size;
if (DECRYPTION_TEST){
if ( !(output[0] == 0x8d || output[0] == 0x8e || output[0] == 0x20)) printf("***ERROR AUDIO FRAME IS NOT AAC_ELD OR ALAC\n");
printf("%d after %s\n", payload_size, utils_data_to_string(output,16,16 ));
if (payload_size && DECRYPTION_TEST){
if ( !(output[0] == 0x8d || output[0] == 0x8e || output[0] == 0x81 || output[0] == 0x82 || output[0] == 0x20)) {
printf("***ERROR AUDIO FRAME IS NOT AAC_ELD OR ALAC\n");
}
if (DECRYPTION_TEST == 2) {
printf("decrypted audio frame, len = %d\n", *outputlen);
printf("%s",utils_data_to_string(output,payload_size,16));
printf("\n");
} else {
printf("%d after %s\n", payload_size, utils_data_to_string(output,16,16 ));
}
}
#ifdef DUMP_AUDIO
// Decrypted file

View File

@@ -352,7 +352,10 @@ raop_handler_setup(raop_conn_t *conn,
unsigned char aesiv[16];
unsigned char aeskey_old[16];
unsigned char aeskey[16];
unsigned char *aeskey_audio = aeskey;
unsigned char *aeskey_video = aeskey;
logger_log(conn->raop->logger, LOGGER_DEBUG, "SETUP 1");
// First setup
@@ -399,25 +402,38 @@ raop_handler_setup(raop_conn_t *conn,
logger_log(conn->raop->logger, LOGGER_DEBUG, "16 byte aeskey after sha-256 hash with ecdh_secret:\n%s", str);
free(str);
/* old-protocol clients such as AirMyPC use the unhashed key aeskey_old for both audio and video */
/* OLD_PROTOCOL_AUDIO_CLIENT_LIST, OLD_PROTOCOL_VIDEO_CLIENT_LIST are defined in global.h */
const char * user_agent = http_request_get_header(request, "User-Agent");
logger_log(conn->raop->logger, LOGGER_INFO, "Client identified as User-Agent: %s", user_agent);
unsigned char *aeskey_audio, *aeskey_video;
if (strstr(OLD_PROTOCOL_AUDIO_CLIENT_LIST,user_agent)) { /* old-protocol clients use the unhashed AES key */
logger_log(conn->raop->logger, LOGGER_INFO, "This identifies client as using old protocol for AES audio key)");
aeskey_audio = aeskey_old;
} else {
aeskey_audio = aeskey;
/* old-protocol clients such as AirMyPC use the unhashed key aeskey_old for both audio and video (ios9, ios10 support)*/
/* clients with sourceVersion <= OLD_PROTOCOL_AUDIO_CLIENT_SOURCEVERSION use unhashed aeskey_old for audio decryption */
/* this is also done for audio or video if clients User-Agent string is included in OLD_PROTOCOL_[AUDIO,VIDEO]_CLIENT_LIST (AirMyPC support)*/
/* OLD_PROTOCOL_AUDIO_CLIENT_LIST, OLD_PROTOCOL_VIDEO_CLIENT_LIST, OLD_PROTOCOL_AUDIO_CLIENT_SOURCEVERSION are defined in global.h */
plist_t req_source_version_node = plist_dict_get_item(req_root_node, "sourceVersion");
char *sourceVersion;
plist_get_string_val(req_source_version_node, &sourceVersion);
const char *user_agent = http_request_get_header(request, "User-Agent");
logger_log(conn->raop->logger, LOGGER_INFO, "Client identified as User-Agent: %s, sourceVersion: %s", user_agent, sourceVersion);
#ifdef OLD_PROTOCOL_AUDIO_CLIENT_SOURCEVERSION
char *end_ptr;
if (strtoul(sourceVersion, &end_ptr, 10) <= strtoul(OLD_PROTOCOL_AUDIO_CLIENT_SOURCEVERSION , &end_ptr, 10)) aeskey_audio = aeskey_old;
#endif
#ifdef OLD_PROTOCOL_AUDIO_CLIENT_USER_AGENT_LIST
if (strstr(OLD_PROTOCOL_AUDIO_CLIENT_USER_AGENT_LIST, user_agent)) aeskey_audio = aeskey_old;
#endif
#ifdef OLD_PROTOCOL_VIDEO_CLIENT_USER_AGENT_LIST
if (strstr(OLD_PROTOCOL_AUDIO_CLIENT_USER_AGENT_LIST, user_agent)) aeskey_video = aeskey_old;
#endif
if (aeskey_audio == aeskey_old) {
logger_log(conn->raop->logger, LOGGER_INFO, "Client identifed as using old protocol (unhashed) AES audio key)");
}
if (strstr(OLD_PROTOCOL_VIDEO_CLIENT_LIST, user_agent)) { /* old-protocol clients use the unhashed AES key */
logger_log(conn->raop->logger, LOGGER_INFO, "This identifies client as using old protocol for AES video key)");
aeskey_video = aeskey_old;
} else {
aeskey_video = aeskey;
if (aeskey_video == aeskey_old) {
logger_log(conn->raop->logger, LOGGER_INFO, "Client identifed as using old protocol (unhashed) AES video key)");
}
// Time port
uint64_t timing_rport;
plist_t time_note = plist_dict_get_item(req_root_node, "timingPort");