| Index: src/mtpz.c
|
| diff --git a/src/mtpz.c b/src/mtpz.c
|
| index a07fd9e05a38854534f02db2569549e101518dfd..0cb9d8fe17d1268cd17288eeec6f1b8937450ee8 100644
|
| --- a/src/mtpz.c
|
| +++ b/src/mtpz.c
|
| @@ -19,8 +19,6 @@
|
| * Boston, MA 02111-1307, USA.
|
| *
|
| * This file provides mtp zune cryptographic setup interfaces.
|
| - * It is also used with Windows Phone 7, but Microsoft/Nokiad seem
|
| - * to have discontinued MTPZ on Windows Phone 8.
|
| *
|
| * DISCLAIMER:
|
| *
|
| @@ -117,10 +115,9 @@ static char *hex_to_bytes(char *hex, size_t len)
|
| int mtpz_loaddata()
|
| {
|
| char *home = getenv("HOME");
|
| - int ret = -1;
|
| if (!home)
|
| {
|
| - LIBMTP_ERROR("Unable to determine user's home directory, MTPZ disabled.\n");
|
| + LIBMTP_INFO("Error: Unable to determine user's home directory.\n");
|
| return -1;
|
| }
|
|
|
| @@ -130,66 +127,63 @@ int mtpz_loaddata()
|
|
|
| FILE *fdata = fopen(path, "r");
|
| if (!fdata)
|
| - return ret;
|
| + {
|
| + LIBMTP_INFO("Error: Unable to open ~/.mtpz-data for reading.\n");
|
| + return -1;
|
| + }
|
|
|
| // Should only be six characters in length, but fgets will encounter a newline and stop.
|
| MTPZ_PUBLIC_EXPONENT = (unsigned char *)fgets_strip((char *)malloc(8), 8, fdata);
|
| if (!MTPZ_PUBLIC_EXPONENT)
|
| {
|
| - LIBMTP_ERROR("Unable to read MTPZ public exponent from ~/.mtpz-data, MTPZ disabled.\n");
|
| - goto cleanup;
|
| + LIBMTP_INFO("Error: Unable to read MTPZ public exponent from ~/.mtpz-data\n");
|
| + return -1;
|
| }
|
|
|
| // Should only be 33 characters in length, but fgets will encounter a newline and stop.
|
| - char *hexenckey = fgets_strip((char *)malloc(35), 35, fdata);
|
| + char *hexenckey = (unsigned char *)fgets_strip((char *)malloc(35), 35, fdata);
|
| if (!hexenckey)
|
| {
|
| - LIBMTP_ERROR("Unable to read MTPZ encryption key from ~/.mtpz-data, MTPZ disabled.\n");
|
| - goto cleanup;
|
| + LIBMTP_INFO("Error: Unable to read MTPZ encryption key from ~/.mtpz-data\n");
|
| + return -1;
|
| }
|
| -
|
| MTPZ_ENCRYPTION_KEY = hex_to_bytes(hexenckey, strlen(hexenckey));
|
| if (!MTPZ_ENCRYPTION_KEY)
|
| {
|
| - LIBMTP_ERROR("Unable to read MTPZ encryption key from ~/.mtpz-data, MTPZ disabled.\n");
|
| - goto cleanup;
|
| + LIBMTP_INFO("Error: Unable to read MTPZ encryption key from ~/.mtpz-data\n");
|
| }
|
|
|
| // Should only be 256 characters in length, but fgets will encounter a newline and stop.
|
| MTPZ_MODULUS = (unsigned char *)fgets_strip((char *)malloc(260), 260, fdata);
|
| if (!MTPZ_MODULUS)
|
| {
|
| - LIBMTP_ERROR("Unable to read MTPZ modulus from ~/.mtpz-data, MTPZ disabled.\n");
|
| - goto cleanup;
|
| + LIBMTP_INFO("Error: Unable to read MTPZ modulus from ~/.mtpz-data\n");
|
| + return -1;
|
| }
|
|
|
| // Should only be 256 characters in length, but fgets will encounter a newline and stop.
|
| MTPZ_PRIVATE_KEY = (unsigned char *)fgets_strip((char *)malloc(260), 260, fdata);
|
| if (!MTPZ_PRIVATE_KEY)
|
| {
|
| - LIBMTP_ERROR("Unable to read MTPZ private key from ~/.mtpz-data, MTPZ disabled.\n");
|
| - goto cleanup;
|
| + LIBMTP_INFO("Error: Unable to read MTPZ private key from ~/.mtpz-data\n");
|
| + return -1;
|
| }
|
|
|
| // Should only be 1258 characters in length, but fgets will encounter the end of the file and stop.
|
| char *hexcerts = fgets_strip((char *)malloc(1260), 1260, fdata);
|
| if (!hexcerts)
|
| {
|
| - LIBMTP_ERROR("Unable to read MTPZ certificates from ~/.mtpz-data, MTPZ disabled.\n");
|
| - goto cleanup;
|
| + LIBMTP_INFO("Error: Unable to read MTPZ certificates from ~/.mtpz-data\n");
|
| + return -1;
|
| }
|
| -
|
| MTPZ_CERTIFICATES = hex_to_bytes(hexcerts, strlen(hexcerts));
|
| if (!MTPZ_CERTIFICATES)
|
| {
|
| - LIBMTP_ERROR("Unable to parse MTPZ certificates from ~/.mtpz-data, MTPZ disabled.\n");
|
| - goto cleanup;
|
| + LIBMTP_INFO("Error: Unable to parse MTPZ certificates from ~/.mtpz-data\n");
|
| + return -1;
|
| }
|
| - // If all done without errors, drop the fail
|
| - ret = 0;
|
| -cleanup:
|
| - fclose(fdata);
|
| - return ret;
|
| +
|
| + return 0;
|
| }
|
| /* MTPZ RSA */
|
|
|
| @@ -242,7 +236,7 @@ unsigned int mtpz_aes_gb9[];
|
| #define MTPZ_ENCRYPTIONBYTE2(val) (((val) >> 8) & 0xFF)
|
| #define MTPZ_ENCRYPTIONBYTE3(val) (((val) >> 0) & 0xFF)
|
|
|
| -#define MTPZ_SWAP(x) mtpz_bswap32(x)
|
| +#define MTPZ_SWAP(x) __builtin_bswap32(x)
|
|
|
| void mtpz_encryption_cipher(unsigned char *data, unsigned int len, char encrypt);
|
| void mtpz_encryption_cipher_advanced(unsigned char *key, unsigned int key_len, unsigned char *data, unsigned int data_len, char encrypt);
|
| @@ -254,25 +248,13 @@ void mtpz_encryption_encrypt_custom(unsigned char *data, unsigned char *seed, un
|
| void mtpz_encryption_encrypt_mac(unsigned char *hash, unsigned int hash_length, unsigned char *seed, unsigned int seed_len, unsigned char *out);
|
|
|
|
|
| -static inline uint32_t mtpz_bswap32(uint32_t x)
|
| -{
|
| -#if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) || defined(__clang__)
|
| - return __builtin_bswap32(x);
|
| -#else
|
| - return (x >> 24) |
|
| - ((x >> 8) & 0x0000ff00) |
|
| - ((x << 8) & 0x00ff0000) |
|
| - (x << 24);
|
| -#endif
|
| -}
|
|
|
|
|
| /* MTPZ RSA implementation */
|
| mtpz_rsa_t *mtpz_rsa_init(const unsigned char *str_modulus, const unsigned char *str_privkey, const unsigned char *str_pubexp)
|
| {
|
| - mtpz_rsa_t *rsa = calloc(1, sizeof(mtpz_rsa_t));
|
| - if (rsa == NULL)
|
| - return NULL;
|
| + mtpz_rsa_t *rsa = (mtpz_rsa_t *)malloc(sizeof(mtpz_rsa_t));
|
| + memset(rsa, 0, sizeof(rsa));
|
|
|
| gcry_mpi_t mpi_modulus, mpi_privkey, mpi_pubexp;
|
|
|
| @@ -1511,133 +1493,134 @@ ptp_mtpz_validatehandshakeresponse (PTPParams* params, unsigned char *random, un
|
| unsigned char* response = NULL;
|
|
|
| ret = ptp_mtpz_getwmdrmpdappresponse (params, &response, &len);
|
| - if (ret != PTP_RC_OK)
|
| + if (ret == PTP_RC_OK)
|
| {
|
| - LIBMTP_INFO ("(MTPZ) Failure - did not receive device's response.\n");
|
| - return ret;
|
| - }
|
| + char *reader = (char *)response;
|
| + int i;
|
|
|
| - char *reader = (char *)response;
|
| - int i;
|
| + if (*(reader++) != '\x02')
|
| + {
|
| + return -1;
|
| + }
|
|
|
| - if (*(reader++) != '\x02')
|
| - {
|
| - return -1;
|
| - }
|
| + if (*(reader++) != '\x02')
|
| + {
|
| + return -1;
|
| + }
|
|
|
| - if (*(reader++) != '\x02')
|
| - {
|
| - return -1;
|
| - }
|
| + // Message is always 128 bytes.
|
| + reader++;
|
| + if (*(reader++) != '\x80')
|
| + {
|
| + return -1;
|
| + }
|
|
|
| - // Message is always 128 bytes.
|
| - reader++;
|
| - if (*(reader++) != '\x80')
|
| - {
|
| - return -1;
|
| - }
|
| + char *message = (char *)malloc(128);
|
| + memcpy(message, reader, 128);
|
| + reader += 128;
|
|
|
| - char *message = (char *)malloc(128);
|
| - memcpy(message, reader, 128);
|
| - reader += 128;
|
| + // Decrypt the hash-key-message..
|
| + char *msg_dec = (char *)malloc(128);
|
| + memset(msg_dec, 0, 128);
|
|
|
| - // Decrypt the hash-key-message..
|
| - char *msg_dec = (char *)malloc(128);
|
| - memset(msg_dec, 0, 128);
|
| + mtpz_rsa_t *rsa = mtpz_rsa_init(MTPZ_MODULUS, MTPZ_PRIVATE_KEY, MTPZ_PUBLIC_EXPONENT);
|
| + if (!rsa)
|
| + {
|
| + LIBMTP_INFO ("(MTPZ) Failure - could not instantiate RSA object.\n");
|
| + free(message);
|
| + free(msg_dec);
|
| + return -1;
|
| + }
|
|
|
| - mtpz_rsa_t *rsa = mtpz_rsa_init(MTPZ_MODULUS, MTPZ_PRIVATE_KEY, MTPZ_PUBLIC_EXPONENT);
|
| - if (!rsa)
|
| - {
|
| - LIBMTP_INFO ("(MTPZ) Failure - could not instantiate RSA object.\n");
|
| - free(message);
|
| - free(msg_dec);
|
| - return -1;
|
| - }
|
| + if (mtpz_rsa_decrypt(128, (unsigned char *)message, 128, (unsigned char *)msg_dec, rsa) == 0)
|
| + {
|
| + LIBMTP_INFO ("(MTPZ) Failure - could not perform RSA decryption.\n");
|
|
|
| - if (mtpz_rsa_decrypt(128, (unsigned char *)message, 128, (unsigned char *)msg_dec, rsa) == 0)
|
| - {
|
| - LIBMTP_INFO ("(MTPZ) Failure - could not perform RSA decryption.\n");
|
| + free(message);
|
| + free(msg_dec);
|
| + mtpz_rsa_free(rsa);
|
| + return -1;
|
| + }
|
|
|
| - free(message);
|
| - free(msg_dec);
|
| mtpz_rsa_free(rsa);
|
| - return -1;
|
| - }
|
| -
|
| - mtpz_rsa_free(rsa);
|
| - rsa = NULL;
|
| + rsa = NULL;
|
|
|
| - char *state = mtpz_hash_init_state();
|
| - char *hash_key = (char *)malloc(16);
|
| - char *v10 = mtpz_hash_custom6A5DC(state, msg_dec + 21, 107, 20);
|
| + char *state = mtpz_hash_init_state();
|
| + char *hash_key = (char *)malloc(16);
|
| + char *v10 = mtpz_hash_custom6A5DC(state, msg_dec + 21, 107, 20);
|
|
|
| - for (i = 0; i < 20; i++)
|
| - msg_dec[i + 1] ^= v10[i];
|
| + for (i = 0; i < 20; i++)
|
| + msg_dec[i + 1] ^= v10[i];
|
|
|
| - char *v11 = mtpz_hash_custom6A5DC(state, msg_dec + 1, 20, 107);
|
| + char *v11 = mtpz_hash_custom6A5DC(state, msg_dec + 1, 20, 107);
|
|
|
| - for (i = 0; i < 107; i++)
|
| - msg_dec[i + 21] ^= v11[i];
|
| + for (i = 0; i < 107; i++)
|
| + msg_dec[i + 21] ^= v11[i];
|
|
|
| - memcpy(hash_key, msg_dec + 112, 16);
|
| + memcpy(hash_key, msg_dec + 112, 16);
|
|
|
| - // Encrypted message is 0x340 bytes.
|
| - reader += 2;
|
| - if (*(reader++) != '\x03' || *(reader++) != '\x40')
|
| - {
|
| - return -1;
|
| - }
|
| + // Encrypted message is 0x340 bytes.
|
| + reader += 2;
|
| + if (*(reader++) != '\x03' || *(reader++) != '\x40')
|
| + {
|
| + return -1;
|
| + }
|
|
|
| - unsigned char *act_msg = (unsigned char *)malloc(832);
|
| - unsigned char *act_reader = act_msg;
|
| - memcpy(act_msg, reader, 832);
|
| - reader = NULL;
|
| + unsigned char *act_msg = (unsigned char *)malloc(832);
|
| + unsigned char *act_reader = act_msg;
|
| + memcpy(act_msg, reader, 832);
|
| + reader = NULL;
|
|
|
| - mtpz_encryption_cipher_advanced((unsigned char *)hash_key, 16, act_msg, 832, 0);
|
| + mtpz_encryption_cipher_advanced((unsigned char *)hash_key, 16, act_msg, 832, 0);
|
|
|
| - act_reader++;
|
| - unsigned int certs_length = MTPZ_SWAP(*(unsigned int *)(act_reader));
|
| - act_reader += 4;
|
| - act_reader += certs_length;
|
| + act_reader++;
|
| + unsigned int certs_length = __builtin_bswap32(*(unsigned int *)(act_reader));
|
| + act_reader += 4;
|
| + act_reader += certs_length;
|
|
|
| - unsigned int rand_length = MTPZ_SWAP(*(unsigned short *)(act_reader) << 16);
|
| - act_reader += 2;
|
| - unsigned char *rand_data = (unsigned char *)malloc(rand_length);
|
| - memcpy(rand_data, act_reader, rand_length);
|
| - if (memcmp(rand_data, random, 16) != 0)
|
| - {
|
| + unsigned int rand_length = __builtin_bswap32(*(unsigned short *)(act_reader) << 16);
|
| + act_reader += 2;
|
| + unsigned char *rand_data = (unsigned char *)malloc(rand_length);
|
| + memcpy(rand_data, act_reader, rand_length);
|
| + if (memcmp(rand_data, random, 16) != 0)
|
| + {
|
| + free(rand_data);
|
| + return -1;
|
| + }
|
| free(rand_data);
|
| - return -1;
|
| - }
|
| - free(rand_data);
|
| - act_reader += rand_length;
|
| + act_reader += rand_length;
|
|
|
| - unsigned int dev_rand_length = MTPZ_SWAP(*(unsigned short *)(act_reader) << 16);
|
| - act_reader += 2;
|
| - act_reader += dev_rand_length;
|
| + unsigned int dev_rand_length = __builtin_bswap32(*(unsigned short *)(act_reader) << 16);
|
| + act_reader += 2;
|
| + act_reader += dev_rand_length;
|
|
|
| - act_reader++;
|
| + act_reader++;
|
|
|
| - unsigned int sig_length = MTPZ_SWAP(*(unsigned short *)(act_reader) << 16);
|
| - act_reader += 2;
|
| - act_reader += sig_length;
|
| + unsigned int sig_length = __builtin_bswap32(*(unsigned short *)(act_reader) << 16);
|
| + act_reader += 2;
|
| + act_reader += sig_length;
|
|
|
| - act_reader++;
|
| + act_reader++;
|
|
|
| - unsigned int machash_length = MTPZ_SWAP(*(unsigned short *)(act_reader) << 16);
|
| - act_reader += 2;
|
| - unsigned char *machash_data = (unsigned char *)malloc(machash_length);
|
| - memcpy(machash_data, act_reader, machash_length);
|
| - act_reader += machash_length;
|
| + unsigned int machash_length = __builtin_bswap32(*(unsigned short *)(act_reader) << 16);
|
| + act_reader += 2;
|
| + unsigned char *machash_data = (unsigned char *)malloc(machash_length);
|
| + memcpy(machash_data, act_reader, machash_length);
|
| + act_reader += machash_length;
|
|
|
| - *calculatedHash = machash_data;
|
| + *calculatedHash = machash_data;
|
|
|
| - free(message);
|
| - free(msg_dec);
|
| - free(state);
|
| - free(v10);
|
| - free(v11);
|
| - free(act_msg);
|
| + free(message);
|
| + free(msg_dec);
|
| + free(state);
|
| + free(v10);
|
| + free(v11);
|
| + free(act_msg);
|
| + }
|
| + else
|
| + {
|
| + LIBMTP_INFO ("(MTPZ) Failure - did not receive device's response.\n");
|
| + }
|
|
|
| return ret;
|
| }
|
| @@ -1653,8 +1636,8 @@ ptp_mtpz_opensecuresyncsession (PTPParams* params, unsigned char *hash)
|
| mtpz_encryption_encrypt_mac(hash, 16, (unsigned char *)(&macCount), 4, mch);
|
|
|
| ret = ptp_mtpz_wmdrmpd_enabletrustedfilesoperations(params,
|
| - MTPZ_SWAP(hashparams[0]), MTPZ_SWAP(hashparams[1]),
|
| - MTPZ_SWAP(hashparams[2]), MTPZ_SWAP(hashparams[3]));
|
| + __builtin_bswap32(hashparams[0]), __builtin_bswap32(hashparams[1]),
|
| + __builtin_bswap32(hashparams[2]), __builtin_bswap32(hashparams[3]));
|
| return ret;
|
| };
|
|
|
|
|