| OLD | NEW |
| 1 /** | 1 /** |
| 2 * \file mtpz.c | 2 * \file mtpz.c |
| 3 * | 3 * |
| 4 * Copyright (C) 2011-2012 Sajid Anwar <sajidanwar94@gmail.com> | 4 * Copyright (C) 2011-2012 Sajid Anwar <sajidanwar94@gmail.com> |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Lesser General Public | 7 * modify it under the terms of the GNU Lesser General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
| 10 * | 10 * |
| 11 * This library is distributed in the hope that it will be useful, | 11 * This library is distributed in the hope that it will be useful, |
| 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 * Lesser General Public License for more details. | 14 * Lesser General Public License for more details. |
| 15 * | 15 * |
| 16 * You should have received a copy of the GNU Lesser General Public | 16 * You should have received a copy of the GNU Lesser General Public |
| 17 * License along with this library; if not, write to the | 17 * License along with this library; if not, write to the |
| 18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| 19 * Boston, MA 02111-1307, USA. | 19 * Boston, MA 02111-1307, USA. |
| 20 * | 20 * |
| 21 * This file provides mtp zune cryptographic setup interfaces. | 21 * This file provides mtp zune cryptographic setup interfaces. |
| 22 * It is also used with Windows Phone 7, but Microsoft/Nokiad seem | |
| 23 * to have discontinued MTPZ on Windows Phone 8. | |
| 24 * | 22 * |
| 25 * DISCLAIMER: | 23 * DISCLAIMER: |
| 26 * | 24 * |
| 27 * The intention of this implementation is for users to be able | 25 * The intention of this implementation is for users to be able |
| 28 * to interoperate with their devices, i.e. copy music to them in | 26 * to interoperate with their devices, i.e. copy music to them in |
| 29 * operating systems other than Microsoft Windows, so it can be | 27 * operating systems other than Microsoft Windows, so it can be |
| 30 * played back on the device. We do not provide encryption keys | 28 * played back on the device. We do not provide encryption keys |
| 31 * and constants in libmtp, we never will. You have to have these | 29 * and constants in libmtp, we never will. You have to have these |
| 32 * on file in your home directory in $HOME/.mtpz-data, and we suggest | 30 * on file in your home directory in $HOME/.mtpz-data, and we suggest |
| 33 * that you talk to Microsoft about providing the proper numbers if | 31 * that you talk to Microsoft about providing the proper numbers if |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 bytes[i / 2] = u; | 108 bytes[i / 2] = u; |
| 111 i += 2; | 109 i += 2; |
| 112 } | 110 } |
| 113 | 111 |
| 114 return bytes; | 112 return bytes; |
| 115 } | 113 } |
| 116 | 114 |
| 117 int mtpz_loaddata() | 115 int mtpz_loaddata() |
| 118 { | 116 { |
| 119 char *home = getenv("HOME"); | 117 char *home = getenv("HOME"); |
| 120 int ret = -1; | |
| 121 if (!home) | 118 if (!home) |
| 122 { | 119 { |
| 123 » » LIBMTP_ERROR("Unable to determine user's home directory, MTPZ di
sabled.\n"); | 120 » » LIBMTP_INFO("Error: Unable to determine user's home directory.\n
"); |
| 124 return -1; | 121 return -1; |
| 125 } | 122 } |
| 126 | 123 |
| 127 int plen = strlen(home) + strlen("/.mtpz-data") + 1; | 124 int plen = strlen(home) + strlen("/.mtpz-data") + 1; |
| 128 char path[plen]; | 125 char path[plen]; |
| 129 sprintf(path, "%s/.mtpz-data", home); | 126 sprintf(path, "%s/.mtpz-data", home); |
| 130 | 127 |
| 131 FILE *fdata = fopen(path, "r"); | 128 FILE *fdata = fopen(path, "r"); |
| 132 if (!fdata) | 129 if (!fdata) |
| 133 » » return ret; | 130 » { |
| 131 » » LIBMTP_INFO("Error: Unable to open ~/.mtpz-data for reading.\n")
; |
| 132 » » return -1; |
| 133 » } |
| 134 | 134 |
| 135 // Should only be six characters in length, but fgets will encounter a n
ewline and stop. | 135 // Should only be six characters in length, but fgets will encounter a n
ewline and stop. |
| 136 MTPZ_PUBLIC_EXPONENT = (unsigned char *)fgets_strip((char *)malloc(8), 8
, fdata); | 136 MTPZ_PUBLIC_EXPONENT = (unsigned char *)fgets_strip((char *)malloc(8), 8
, fdata); |
| 137 if (!MTPZ_PUBLIC_EXPONENT) | 137 if (!MTPZ_PUBLIC_EXPONENT) |
| 138 { | 138 { |
| 139 » » LIBMTP_ERROR("Unable to read MTPZ public exponent from ~/.mtpz-d
ata, MTPZ disabled.\n"); | 139 » » LIBMTP_INFO("Error: Unable to read MTPZ public exponent from ~/.
mtpz-data\n"); |
| 140 » » goto cleanup; | 140 » » return -1; |
| 141 } | 141 } |
| 142 | 142 |
| 143 // Should only be 33 characters in length, but fgets will encounter a ne
wline and stop. | 143 // Should only be 33 characters in length, but fgets will encounter a ne
wline and stop. |
| 144 » char *hexenckey = fgets_strip((char *)malloc(35), 35, fdata); | 144 » char *hexenckey = (unsigned char *)fgets_strip((char *)malloc(35), 35, f
data); |
| 145 if (!hexenckey) | 145 if (!hexenckey) |
| 146 { | 146 { |
| 147 » » LIBMTP_ERROR("Unable to read MTPZ encryption key from ~/.mtpz-da
ta, MTPZ disabled.\n"); | 147 » » LIBMTP_INFO("Error: Unable to read MTPZ encryption key from ~/.m
tpz-data\n"); |
| 148 » » goto cleanup; | 148 » » return -1; |
| 149 } | 149 } |
| 150 | |
| 151 MTPZ_ENCRYPTION_KEY = hex_to_bytes(hexenckey, strlen(hexenckey)); | 150 MTPZ_ENCRYPTION_KEY = hex_to_bytes(hexenckey, strlen(hexenckey)); |
| 152 if (!MTPZ_ENCRYPTION_KEY) | 151 if (!MTPZ_ENCRYPTION_KEY) |
| 153 { | 152 { |
| 154 » » LIBMTP_ERROR("Unable to read MTPZ encryption key from ~/.mtpz-da
ta, MTPZ disabled.\n"); | 153 » » LIBMTP_INFO("Error: Unable to read MTPZ encryption key from ~/.m
tpz-data\n"); |
| 155 » » goto cleanup; | |
| 156 } | 154 } |
| 157 | 155 |
| 158 // Should only be 256 characters in length, but fgets will encounter a n
ewline and stop. | 156 // Should only be 256 characters in length, but fgets will encounter a n
ewline and stop. |
| 159 MTPZ_MODULUS = (unsigned char *)fgets_strip((char *)malloc(260), 260, fd
ata); | 157 MTPZ_MODULUS = (unsigned char *)fgets_strip((char *)malloc(260), 260, fd
ata); |
| 160 if (!MTPZ_MODULUS) | 158 if (!MTPZ_MODULUS) |
| 161 { | 159 { |
| 162 » » LIBMTP_ERROR("Unable to read MTPZ modulus from ~/.mtpz-data, MTP
Z disabled.\n"); | 160 » » LIBMTP_INFO("Error: Unable to read MTPZ modulus from ~/.mtpz-dat
a\n"); |
| 163 » » goto cleanup; | 161 » » return -1; |
| 164 } | 162 } |
| 165 | 163 |
| 166 // Should only be 256 characters in length, but fgets will encounter a n
ewline and stop. | 164 // Should only be 256 characters in length, but fgets will encounter a n
ewline and stop. |
| 167 MTPZ_PRIVATE_KEY = (unsigned char *)fgets_strip((char *)malloc(260), 260
, fdata); | 165 MTPZ_PRIVATE_KEY = (unsigned char *)fgets_strip((char *)malloc(260), 260
, fdata); |
| 168 if (!MTPZ_PRIVATE_KEY) | 166 if (!MTPZ_PRIVATE_KEY) |
| 169 { | 167 { |
| 170 » » LIBMTP_ERROR("Unable to read MTPZ private key from ~/.mtpz-data,
MTPZ disabled.\n"); | 168 » » LIBMTP_INFO("Error: Unable to read MTPZ private key from ~/.mtpz
-data\n"); |
| 171 » » goto cleanup; | 169 » » return -1; |
| 172 } | 170 } |
| 173 | 171 |
| 174 // Should only be 1258 characters in length, but fgets will encounter th
e end of the file and stop. | 172 // Should only be 1258 characters in length, but fgets will encounter th
e end of the file and stop. |
| 175 char *hexcerts = fgets_strip((char *)malloc(1260), 1260, fdata); | 173 char *hexcerts = fgets_strip((char *)malloc(1260), 1260, fdata); |
| 176 if (!hexcerts) | 174 if (!hexcerts) |
| 177 { | 175 { |
| 178 » » LIBMTP_ERROR("Unable to read MTPZ certificates from ~/.mtpz-data
, MTPZ disabled.\n"); | 176 » » LIBMTP_INFO("Error: Unable to read MTPZ certificates from ~/.mtp
z-data\n"); |
| 179 » » goto cleanup; | 177 » » return -1; |
| 180 } | 178 } |
| 181 | |
| 182 MTPZ_CERTIFICATES = hex_to_bytes(hexcerts, strlen(hexcerts)); | 179 MTPZ_CERTIFICATES = hex_to_bytes(hexcerts, strlen(hexcerts)); |
| 183 if (!MTPZ_CERTIFICATES) | 180 if (!MTPZ_CERTIFICATES) |
| 184 { | 181 { |
| 185 » » LIBMTP_ERROR("Unable to parse MTPZ certificates from ~/.mtpz-dat
a, MTPZ disabled.\n"); | 182 » » LIBMTP_INFO("Error: Unable to parse MTPZ certificates from ~/.mt
pz-data\n"); |
| 186 » » goto cleanup; | 183 » » return -1; |
| 187 } | 184 } |
| 188 » // If all done without errors, drop the fail | 185 |
| 189 » ret = 0; | 186 » return 0; |
| 190 cleanup: | |
| 191 » fclose(fdata); | |
| 192 » return ret; | |
| 193 } | 187 } |
| 194 /* MTPZ RSA */ | 188 /* MTPZ RSA */ |
| 195 | 189 |
| 196 typedef struct mtpz_rsa_struct | 190 typedef struct mtpz_rsa_struct |
| 197 { | 191 { |
| 198 gcry_sexp_t privkey; | 192 gcry_sexp_t privkey; |
| 199 gcry_sexp_t pubkey; | 193 gcry_sexp_t pubkey; |
| 200 } mtpz_rsa_t; | 194 } mtpz_rsa_t; |
| 201 | 195 |
| 202 mtpz_rsa_t *mtpz_rsa_init(const unsigned char *modulus, const unsigned char *pri
v_key, const unsigned char *pub_exp); | 196 mtpz_rsa_t *mtpz_rsa_init(const unsigned char *modulus, const unsigned char *pri
v_key, const unsigned char *pub_exp); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 unsigned int mtpz_aes_gb11[]; | 229 unsigned int mtpz_aes_gb11[]; |
| 236 unsigned int mtpz_aes_gb14[]; | 230 unsigned int mtpz_aes_gb14[]; |
| 237 unsigned int mtpz_aes_gb13[]; | 231 unsigned int mtpz_aes_gb13[]; |
| 238 unsigned int mtpz_aes_gb9[]; | 232 unsigned int mtpz_aes_gb9[]; |
| 239 | 233 |
| 240 #define MTPZ_ENCRYPTIONLOBYTE(val) (((val) >> 24) & 0xFF) | 234 #define MTPZ_ENCRYPTIONLOBYTE(val) (((val) >> 24) & 0xFF) |
| 241 #define MTPZ_ENCRYPTIONBYTE1(val) (((val) >> 16) & 0xFF) | 235 #define MTPZ_ENCRYPTIONBYTE1(val) (((val) >> 16) & 0xFF) |
| 242 #define MTPZ_ENCRYPTIONBYTE2(val) (((val) >> 8) & 0xFF) | 236 #define MTPZ_ENCRYPTIONBYTE2(val) (((val) >> 8) & 0xFF) |
| 243 #define MTPZ_ENCRYPTIONBYTE3(val) (((val) >> 0) & 0xFF) | 237 #define MTPZ_ENCRYPTIONBYTE3(val) (((val) >> 0) & 0xFF) |
| 244 | 238 |
| 245 #define MTPZ_SWAP(x) mtpz_bswap32(x) | 239 #define MTPZ_SWAP(x) __builtin_bswap32(x) |
| 246 | 240 |
| 247 void mtpz_encryption_cipher(unsigned char *data, unsigned int len, char encrypt)
; | 241 void mtpz_encryption_cipher(unsigned char *data, unsigned int len, char encrypt)
; |
| 248 void mtpz_encryption_cipher_advanced(unsigned char *key, unsigned int key_len, u
nsigned char *data, unsigned int data_len, char encrypt); | 242 void mtpz_encryption_cipher_advanced(unsigned char *key, unsigned int key_len, u
nsigned char *data, unsigned int data_len, char encrypt); |
| 249 unsigned char *mtpz_encryption_expand_key(unsigned char *constant, int key_len,
int count, int *out_len); | 243 unsigned char *mtpz_encryption_expand_key(unsigned char *constant, int key_len,
int count, int *out_len); |
| 250 void mtpz_encryption_expand_key_inner(unsigned char *constant, int key_len, unsi
gned char **out, int *out_len); | 244 void mtpz_encryption_expand_key_inner(unsigned char *constant, int key_len, unsi
gned char **out, int *out_len); |
| 251 void mtpz_encryption_inv_mix_columns(unsigned char *expanded, int offset, int ro
unds); | 245 void mtpz_encryption_inv_mix_columns(unsigned char *expanded, int offset, int ro
unds); |
| 252 void mtpz_encryption_decrypt_custom(unsigned char *data, unsigned char *seed, un
signed char *expanded); | 246 void mtpz_encryption_decrypt_custom(unsigned char *data, unsigned char *seed, un
signed char *expanded); |
| 253 void mtpz_encryption_encrypt_custom(unsigned char *data, unsigned char *seed, un
signed char *expanded); | 247 void mtpz_encryption_encrypt_custom(unsigned char *data, unsigned char *seed, un
signed char *expanded); |
| 254 void mtpz_encryption_encrypt_mac(unsigned char *hash, unsigned int hash_length,
unsigned char *seed, unsigned int seed_len, unsigned char *out); | 248 void mtpz_encryption_encrypt_mac(unsigned char *hash, unsigned int hash_length,
unsigned char *seed, unsigned int seed_len, unsigned char *out); |
| 255 | 249 |
| 256 | 250 |
| 257 static inline uint32_t mtpz_bswap32(uint32_t x) | |
| 258 { | |
| 259 #if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
|| defined(__clang__) | |
| 260 return __builtin_bswap32(x); | |
| 261 #else | |
| 262 return (x >> 24) | | |
| 263 ((x >> 8) & 0x0000ff00) | | |
| 264 ((x << 8) & 0x00ff0000) | | |
| 265 (x << 24); | |
| 266 #endif | |
| 267 } | |
| 268 | 251 |
| 269 | 252 |
| 270 /* MTPZ RSA implementation */ | 253 /* MTPZ RSA implementation */ |
| 271 mtpz_rsa_t *mtpz_rsa_init(const unsigned char *str_modulus, const unsigned char
*str_privkey, const unsigned char *str_pubexp) | 254 mtpz_rsa_t *mtpz_rsa_init(const unsigned char *str_modulus, const unsigned char
*str_privkey, const unsigned char *str_pubexp) |
| 272 { | 255 { |
| 273 » mtpz_rsa_t *rsa = calloc(1, sizeof(mtpz_rsa_t)); | 256 » mtpz_rsa_t *rsa = (mtpz_rsa_t *)malloc(sizeof(mtpz_rsa_t)); |
| 274 » if (rsa == NULL) | 257 » memset(rsa, 0, sizeof(rsa)); |
| 275 » » return NULL; | |
| 276 | 258 |
| 277 gcry_mpi_t mpi_modulus, mpi_privkey, mpi_pubexp; | 259 gcry_mpi_t mpi_modulus, mpi_privkey, mpi_pubexp; |
| 278 | 260 |
| 279 gcry_mpi_scan(&mpi_modulus, GCRYMPI_FMT_HEX, str_modulus, 0, NULL); | 261 gcry_mpi_scan(&mpi_modulus, GCRYMPI_FMT_HEX, str_modulus, 0, NULL); |
| 280 gcry_mpi_scan(&mpi_privkey, GCRYMPI_FMT_HEX, str_privkey, 0, NULL); | 262 gcry_mpi_scan(&mpi_privkey, GCRYMPI_FMT_HEX, str_privkey, 0, NULL); |
| 281 gcry_mpi_scan(&mpi_pubexp, GCRYMPI_FMT_HEX, str_pubexp, 0, NULL); | 263 gcry_mpi_scan(&mpi_pubexp, GCRYMPI_FMT_HEX, str_pubexp, 0, NULL); |
| 282 | 264 |
| 283 gcry_sexp_build(&rsa->privkey, NULL, "(private-key (rsa (n %m) (e %m) (d
%m)))", mpi_modulus, mpi_pubexp, mpi_privkey); | 265 gcry_sexp_build(&rsa->privkey, NULL, "(private-key (rsa (n %m) (e %m) (d
%m)))", mpi_modulus, mpi_pubexp, mpi_privkey); |
| 284 gcry_sexp_build(&rsa->pubkey, NULL, "(public-key (rsa (n %m) (e %m)))",
mpi_modulus, mpi_pubexp); | 266 gcry_sexp_build(&rsa->pubkey, NULL, "(public-key (rsa (n %m) (e %m)))",
mpi_modulus, mpi_pubexp); |
| 285 | 267 |
| (...skipping 1218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1504 }; | 1486 }; |
| 1505 | 1487 |
| 1506 static uint16_t | 1488 static uint16_t |
| 1507 ptp_mtpz_validatehandshakeresponse (PTPParams* params, unsigned char *random, un
signed char **calculatedHash) | 1489 ptp_mtpz_validatehandshakeresponse (PTPParams* params, unsigned char *random, un
signed char **calculatedHash) |
| 1508 { | 1490 { |
| 1509 uint16_t ret; | 1491 uint16_t ret; |
| 1510 unsigned int len; | 1492 unsigned int len; |
| 1511 unsigned char* response = NULL; | 1493 unsigned char* response = NULL; |
| 1512 | 1494 |
| 1513 ret = ptp_mtpz_getwmdrmpdappresponse (params, &response, &len); | 1495 ret = ptp_mtpz_getwmdrmpdappresponse (params, &response, &len); |
| 1514 » if (ret != PTP_RC_OK) | 1496 » if (ret == PTP_RC_OK) |
| 1515 { | 1497 { |
| 1516 » » LIBMTP_INFO ("(MTPZ) Failure - did not receive device's response
.\n"); | 1498 » » char *reader = (char *)response; |
| 1517 » » return ret; | 1499 » » int i; |
| 1518 » } | |
| 1519 | 1500 |
| 1520 » char *reader = (char *)response; | 1501 » » if (*(reader++) != '\x02') |
| 1521 » int i; | 1502 » » { |
| 1503 » » » return -1; |
| 1504 » » } |
| 1522 | 1505 |
| 1523 » if (*(reader++) != '\x02') | 1506 » » if (*(reader++) != '\x02') |
| 1524 » { | 1507 » » { |
| 1525 » » return -1; | 1508 » » » return -1; |
| 1526 » } | 1509 » » } |
| 1527 | 1510 |
| 1528 » if (*(reader++) != '\x02') | 1511 » » // Message is always 128 bytes. |
| 1529 » { | 1512 » » reader++; |
| 1530 » » return -1; | 1513 » » if (*(reader++) != '\x80') |
| 1531 » } | 1514 » » { |
| 1515 » » » return -1; |
| 1516 » » } |
| 1532 | 1517 |
| 1533 » // Message is always 128 bytes. | 1518 » » char *message = (char *)malloc(128); |
| 1534 » reader++; | 1519 » » memcpy(message, reader, 128); |
| 1535 » if (*(reader++) != '\x80') | 1520 » » reader += 128; |
| 1536 » { | |
| 1537 » » return -1; | |
| 1538 » } | |
| 1539 | 1521 |
| 1540 » char *message = (char *)malloc(128); | 1522 » » // Decrypt the hash-key-message.. |
| 1541 » memcpy(message, reader, 128); | 1523 » » char *msg_dec = (char *)malloc(128); |
| 1542 » reader += 128; | 1524 » » memset(msg_dec, 0, 128); |
| 1543 | 1525 |
| 1544 » // Decrypt the hash-key-message.. | 1526 » » mtpz_rsa_t *rsa = mtpz_rsa_init(MTPZ_MODULUS, MTPZ_PRIVATE_KEY,
MTPZ_PUBLIC_EXPONENT); |
| 1545 » char *msg_dec = (char *)malloc(128); | 1527 » » if (!rsa) |
| 1546 » memset(msg_dec, 0, 128); | 1528 » » { |
| 1529 » » » LIBMTP_INFO ("(MTPZ) Failure - could not instantiate RSA
object.\n"); |
| 1530 » » » free(message); |
| 1531 » » » free(msg_dec); |
| 1532 » » » return -1; |
| 1533 » » } |
| 1547 | 1534 |
| 1548 » mtpz_rsa_t *rsa = mtpz_rsa_init(MTPZ_MODULUS, MTPZ_PRIVATE_KEY, MTPZ_PUB
LIC_EXPONENT); | 1535 » » if (mtpz_rsa_decrypt(128, (unsigned char *)message, 128, (unsign
ed char *)msg_dec, rsa) == 0) |
| 1549 » if (!rsa) | 1536 » » { |
| 1550 » { | 1537 » » » LIBMTP_INFO ("(MTPZ) Failure - could not perform RSA dec
ryption.\n"); |
| 1551 » » LIBMTP_INFO ("(MTPZ) Failure - could not instantiate RSA object.
\n"); | |
| 1552 » » free(message); | |
| 1553 » » free(msg_dec); | |
| 1554 » » return -1; | |
| 1555 » } | |
| 1556 | 1538 |
| 1557 » if (mtpz_rsa_decrypt(128, (unsigned char *)message, 128, (unsigned char
*)msg_dec, rsa) == 0) | 1539 » » » free(message); |
| 1558 » { | 1540 » » » free(msg_dec); |
| 1559 » » LIBMTP_INFO ("(MTPZ) Failure - could not perform RSA decryption.
\n"); | 1541 » » » mtpz_rsa_free(rsa); |
| 1542 » » » return -1; |
| 1543 » » } |
| 1544 |
| 1545 » » mtpz_rsa_free(rsa); |
| 1546 » » rsa = NULL; |
| 1547 |
| 1548 » » char *state = mtpz_hash_init_state(); |
| 1549 » » char *hash_key = (char *)malloc(16); |
| 1550 » » char *v10 = mtpz_hash_custom6A5DC(state, msg_dec + 21, 107, 20); |
| 1551 |
| 1552 » » for (i = 0; i < 20; i++) |
| 1553 » » » msg_dec[i + 1] ^= v10[i]; |
| 1554 |
| 1555 » » char *v11 = mtpz_hash_custom6A5DC(state, msg_dec + 1, 20, 107); |
| 1556 |
| 1557 » » for (i = 0; i < 107; i++) |
| 1558 » » » msg_dec[i + 21] ^= v11[i]; |
| 1559 |
| 1560 » » memcpy(hash_key, msg_dec + 112, 16); |
| 1561 |
| 1562 » » // Encrypted message is 0x340 bytes. |
| 1563 » » reader += 2; |
| 1564 » » if (*(reader++) != '\x03' || *(reader++) != '\x40') |
| 1565 » » { |
| 1566 » » » return -1; |
| 1567 » » } |
| 1568 |
| 1569 » » unsigned char *act_msg = (unsigned char *)malloc(832); |
| 1570 » » unsigned char *act_reader = act_msg; |
| 1571 » » memcpy(act_msg, reader, 832); |
| 1572 » » reader = NULL; |
| 1573 |
| 1574 » » mtpz_encryption_cipher_advanced((unsigned char *)hash_key, 16, a
ct_msg, 832, 0); |
| 1575 |
| 1576 » » act_reader++; |
| 1577 » » unsigned int certs_length = __builtin_bswap32(*(unsigned int *)(
act_reader)); |
| 1578 » » act_reader += 4; |
| 1579 » » act_reader += certs_length; |
| 1580 |
| 1581 » » unsigned int rand_length = __builtin_bswap32(*(unsigned short *)
(act_reader) << 16); |
| 1582 » » act_reader += 2; |
| 1583 » » unsigned char *rand_data = (unsigned char *)malloc(rand_length); |
| 1584 » » memcpy(rand_data, act_reader, rand_length); |
| 1585 » » if (memcmp(rand_data, random, 16) != 0) |
| 1586 » » { |
| 1587 » » » free(rand_data); |
| 1588 » » » return -1; |
| 1589 » » } |
| 1590 » » free(rand_data); |
| 1591 » » act_reader += rand_length; |
| 1592 |
| 1593 » » unsigned int dev_rand_length = __builtin_bswap32(*(unsigned shor
t *)(act_reader) << 16); |
| 1594 » » act_reader += 2; |
| 1595 » » act_reader += dev_rand_length; |
| 1596 |
| 1597 » » act_reader++; |
| 1598 |
| 1599 » » unsigned int sig_length = __builtin_bswap32(*(unsigned short *)(
act_reader) << 16); |
| 1600 » » act_reader += 2; |
| 1601 » » act_reader += sig_length; |
| 1602 |
| 1603 » » act_reader++; |
| 1604 |
| 1605 » » unsigned int machash_length = __builtin_bswap32(*(unsigned short
*)(act_reader) << 16); |
| 1606 » » act_reader += 2; |
| 1607 » » unsigned char *machash_data = (unsigned char *)malloc(machash_le
ngth); |
| 1608 » » memcpy(machash_data, act_reader, machash_length); |
| 1609 » » act_reader += machash_length; |
| 1610 |
| 1611 » » *calculatedHash = machash_data; |
| 1560 | 1612 |
| 1561 free(message); | 1613 free(message); |
| 1562 free(msg_dec); | 1614 free(msg_dec); |
| 1563 » » mtpz_rsa_free(rsa); | 1615 » » free(state); |
| 1564 » » return -1; | 1616 » » free(v10); |
| 1617 » » free(v11); |
| 1618 » » free(act_msg); |
| 1565 } | 1619 } |
| 1566 | 1620 » else |
| 1567 » mtpz_rsa_free(rsa); | |
| 1568 » rsa = NULL; | |
| 1569 | |
| 1570 » char *state = mtpz_hash_init_state(); | |
| 1571 » char *hash_key = (char *)malloc(16); | |
| 1572 » char *v10 = mtpz_hash_custom6A5DC(state, msg_dec + 21, 107, 20); | |
| 1573 | |
| 1574 » for (i = 0; i < 20; i++) | |
| 1575 » » msg_dec[i + 1] ^= v10[i]; | |
| 1576 | |
| 1577 » char *v11 = mtpz_hash_custom6A5DC(state, msg_dec + 1, 20, 107); | |
| 1578 | |
| 1579 » for (i = 0; i < 107; i++) | |
| 1580 » » msg_dec[i + 21] ^= v11[i]; | |
| 1581 | |
| 1582 » memcpy(hash_key, msg_dec + 112, 16); | |
| 1583 | |
| 1584 » // Encrypted message is 0x340 bytes. | |
| 1585 » reader += 2; | |
| 1586 » if (*(reader++) != '\x03' || *(reader++) != '\x40') | |
| 1587 { | 1621 { |
| 1588 » » return -1; | 1622 » » LIBMTP_INFO ("(MTPZ) Failure - did not receive device's response
.\n"); |
| 1589 } | 1623 } |
| 1590 | 1624 |
| 1591 unsigned char *act_msg = (unsigned char *)malloc(832); | |
| 1592 unsigned char *act_reader = act_msg; | |
| 1593 memcpy(act_msg, reader, 832); | |
| 1594 reader = NULL; | |
| 1595 | |
| 1596 mtpz_encryption_cipher_advanced((unsigned char *)hash_key, 16, act_msg,
832, 0); | |
| 1597 | |
| 1598 act_reader++; | |
| 1599 unsigned int certs_length = MTPZ_SWAP(*(unsigned int *)(act_reader)); | |
| 1600 act_reader += 4; | |
| 1601 act_reader += certs_length; | |
| 1602 | |
| 1603 unsigned int rand_length = MTPZ_SWAP(*(unsigned short *)(act_reader) <<
16); | |
| 1604 act_reader += 2; | |
| 1605 unsigned char *rand_data = (unsigned char *)malloc(rand_length); | |
| 1606 memcpy(rand_data, act_reader, rand_length); | |
| 1607 if (memcmp(rand_data, random, 16) != 0) | |
| 1608 { | |
| 1609 free(rand_data); | |
| 1610 return -1; | |
| 1611 } | |
| 1612 free(rand_data); | |
| 1613 act_reader += rand_length; | |
| 1614 | |
| 1615 unsigned int dev_rand_length = MTPZ_SWAP(*(unsigned short *)(act_reader)
<< 16); | |
| 1616 act_reader += 2; | |
| 1617 act_reader += dev_rand_length; | |
| 1618 | |
| 1619 act_reader++; | |
| 1620 | |
| 1621 unsigned int sig_length = MTPZ_SWAP(*(unsigned short *)(act_reader) << 1
6); | |
| 1622 act_reader += 2; | |
| 1623 act_reader += sig_length; | |
| 1624 | |
| 1625 act_reader++; | |
| 1626 | |
| 1627 unsigned int machash_length = MTPZ_SWAP(*(unsigned short *)(act_reader)
<< 16); | |
| 1628 act_reader += 2; | |
| 1629 unsigned char *machash_data = (unsigned char *)malloc(machash_length); | |
| 1630 memcpy(machash_data, act_reader, machash_length); | |
| 1631 act_reader += machash_length; | |
| 1632 | |
| 1633 *calculatedHash = machash_data; | |
| 1634 | |
| 1635 free(message); | |
| 1636 free(msg_dec); | |
| 1637 free(state); | |
| 1638 free(v10); | |
| 1639 free(v11); | |
| 1640 free(act_msg); | |
| 1641 | |
| 1642 return ret; | 1625 return ret; |
| 1643 } | 1626 } |
| 1644 | 1627 |
| 1645 static uint16_t | 1628 static uint16_t |
| 1646 ptp_mtpz_opensecuresyncsession (PTPParams* params, unsigned char *hash) | 1629 ptp_mtpz_opensecuresyncsession (PTPParams* params, unsigned char *hash) |
| 1647 { | 1630 { |
| 1648 unsigned char mch[16]; | 1631 unsigned char mch[16]; |
| 1649 uint32_t *hashparams = (unsigned int *)mch; | 1632 uint32_t *hashparams = (unsigned int *)mch; |
| 1650 unsigned int macCount = *(unsigned int *)(hash + 16); | 1633 unsigned int macCount = *(unsigned int *)(hash + 16); |
| 1651 uint16_t ret; | 1634 uint16_t ret; |
| 1652 | 1635 |
| 1653 mtpz_encryption_encrypt_mac(hash, 16, (unsigned char *)(&macCount), 4, m
ch); | 1636 mtpz_encryption_encrypt_mac(hash, 16, (unsigned char *)(&macCount), 4, m
ch); |
| 1654 | 1637 |
| 1655 ret = ptp_mtpz_wmdrmpd_enabletrustedfilesoperations(params, | 1638 ret = ptp_mtpz_wmdrmpd_enabletrustedfilesoperations(params, |
| 1656 » » MTPZ_SWAP(hashparams[0]), MTPZ_SWAP(hashparams[1]), | 1639 » » __builtin_bswap32(hashparams[0]), __builtin_bswap32(hashparams[1
]), |
| 1657 » » MTPZ_SWAP(hashparams[2]), MTPZ_SWAP(hashparams[3])); | 1640 » » __builtin_bswap32(hashparams[2]), __builtin_bswap32(hashparams[3
])); |
| 1658 return ret; | 1641 return ret; |
| 1659 }; | 1642 }; |
| 1660 | 1643 |
| 1661 static unsigned char * | 1644 static unsigned char * |
| 1662 ptp_mtpz_makeapplicationcertificatemessage (unsigned int *out_len, unsigned char
**out_random) | 1645 ptp_mtpz_makeapplicationcertificatemessage (unsigned int *out_len, unsigned char
**out_random) |
| 1663 { | 1646 { |
| 1664 *out_len = 785; | 1647 *out_len = 785; |
| 1665 | 1648 |
| 1666 unsigned char *acm = (unsigned char *)malloc(785); | 1649 unsigned char *acm = (unsigned char *)malloc(785); |
| 1667 unsigned char *target = acm; | 1650 unsigned char *target = acm; |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1822 free (message); | 1805 free (message); |
| 1823 | 1806 |
| 1824 LIBMTP_INFO ("(MTPZ) Opening secure sync session.\n"); | 1807 LIBMTP_INFO ("(MTPZ) Opening secure sync session.\n"); |
| 1825 ret = ptp_mtpz_opensecuresyncsession(params, hash); | 1808 ret = ptp_mtpz_opensecuresyncsession(params, hash); |
| 1826 free_hash: | 1809 free_hash: |
| 1827 free(hash); | 1810 free(hash); |
| 1828 free_random: | 1811 free_random: |
| 1829 free(random); | 1812 free(random); |
| 1830 return ret; | 1813 return ret; |
| 1831 } | 1814 } |
| OLD | NEW |