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 |