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. |
22 * | 24 * |
23 * DISCLAIMER: | 25 * DISCLAIMER: |
24 * | 26 * |
25 * The intention of this implementation is for users to be able | 27 * The intention of this implementation is for users to be able |
26 * to interoperate with their devices, i.e. copy music to them in | 28 * to interoperate with their devices, i.e. copy music to them in |
27 * operating systems other than Microsoft Windows, so it can be | 29 * operating systems other than Microsoft Windows, so it can be |
28 * played back on the device. We do not provide encryption keys | 30 * played back on the device. We do not provide encryption keys |
29 * and constants in libmtp, we never will. You have to have these | 31 * and constants in libmtp, we never will. You have to have these |
30 * on file in your home directory in $HOME/.mtpz-data, and we suggest | 32 * on file in your home directory in $HOME/.mtpz-data, and we suggest |
31 * that you talk to Microsoft about providing the proper numbers if | 33 * that you talk to Microsoft about providing the proper numbers if |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 bytes[i / 2] = u; | 110 bytes[i / 2] = u; |
109 i += 2; | 111 i += 2; |
110 } | 112 } |
111 | 113 |
112 return bytes; | 114 return bytes; |
113 } | 115 } |
114 | 116 |
115 int mtpz_loaddata() | 117 int mtpz_loaddata() |
116 { | 118 { |
117 char *home = getenv("HOME"); | 119 char *home = getenv("HOME"); |
| 120 int ret = -1; |
118 if (!home) | 121 if (!home) |
119 { | 122 { |
120 » » LIBMTP_INFO("Error: Unable to determine user's home directory.\n
"); | 123 » » LIBMTP_ERROR("Unable to determine user's home directory, MTPZ di
sabled.\n"); |
121 return -1; | 124 return -1; |
122 } | 125 } |
123 | 126 |
124 int plen = strlen(home) + strlen("/.mtpz-data") + 1; | 127 int plen = strlen(home) + strlen("/.mtpz-data") + 1; |
125 char path[plen]; | 128 char path[plen]; |
126 sprintf(path, "%s/.mtpz-data", home); | 129 sprintf(path, "%s/.mtpz-data", home); |
127 | 130 |
128 FILE *fdata = fopen(path, "r"); | 131 FILE *fdata = fopen(path, "r"); |
129 if (!fdata) | 132 if (!fdata) |
130 » { | 133 » » return ret; |
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_INFO("Error: Unable to read MTPZ public exponent from ~/.
mtpz-data\n"); | 139 » » LIBMTP_ERROR("Unable to read MTPZ public exponent from ~/.mtpz-d
ata, MTPZ disabled.\n"); |
140 » » return -1; | 140 » » goto cleanup; |
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 = (unsigned char *)fgets_strip((char *)malloc(35), 35, f
data); | 144 » char *hexenckey = fgets_strip((char *)malloc(35), 35, fdata); |
145 if (!hexenckey) | 145 if (!hexenckey) |
146 { | 146 { |
147 » » LIBMTP_INFO("Error: Unable to read MTPZ encryption key from ~/.m
tpz-data\n"); | 147 » » LIBMTP_ERROR("Unable to read MTPZ encryption key from ~/.mtpz-da
ta, MTPZ disabled.\n"); |
148 » » return -1; | 148 » » goto cleanup; |
149 } | 149 } |
| 150 |
150 MTPZ_ENCRYPTION_KEY = hex_to_bytes(hexenckey, strlen(hexenckey)); | 151 MTPZ_ENCRYPTION_KEY = hex_to_bytes(hexenckey, strlen(hexenckey)); |
151 if (!MTPZ_ENCRYPTION_KEY) | 152 if (!MTPZ_ENCRYPTION_KEY) |
152 { | 153 { |
153 » » LIBMTP_INFO("Error: Unable to read MTPZ encryption key from ~/.m
tpz-data\n"); | 154 » » LIBMTP_ERROR("Unable to read MTPZ encryption key from ~/.mtpz-da
ta, MTPZ disabled.\n"); |
| 155 » » goto cleanup; |
154 } | 156 } |
155 | 157 |
156 // Should only be 256 characters in length, but fgets will encounter a n
ewline and stop. | 158 // Should only be 256 characters in length, but fgets will encounter a n
ewline and stop. |
157 MTPZ_MODULUS = (unsigned char *)fgets_strip((char *)malloc(260), 260, fd
ata); | 159 MTPZ_MODULUS = (unsigned char *)fgets_strip((char *)malloc(260), 260, fd
ata); |
158 if (!MTPZ_MODULUS) | 160 if (!MTPZ_MODULUS) |
159 { | 161 { |
160 » » LIBMTP_INFO("Error: Unable to read MTPZ modulus from ~/.mtpz-dat
a\n"); | 162 » » LIBMTP_ERROR("Unable to read MTPZ modulus from ~/.mtpz-data, MTP
Z disabled.\n"); |
161 » » return -1; | 163 » » goto cleanup; |
162 } | 164 } |
163 | 165 |
164 // Should only be 256 characters in length, but fgets will encounter a n
ewline and stop. | 166 // Should only be 256 characters in length, but fgets will encounter a n
ewline and stop. |
165 MTPZ_PRIVATE_KEY = (unsigned char *)fgets_strip((char *)malloc(260), 260
, fdata); | 167 MTPZ_PRIVATE_KEY = (unsigned char *)fgets_strip((char *)malloc(260), 260
, fdata); |
166 if (!MTPZ_PRIVATE_KEY) | 168 if (!MTPZ_PRIVATE_KEY) |
167 { | 169 { |
168 » » LIBMTP_INFO("Error: Unable to read MTPZ private key from ~/.mtpz
-data\n"); | 170 » » LIBMTP_ERROR("Unable to read MTPZ private key from ~/.mtpz-data,
MTPZ disabled.\n"); |
169 » » return -1; | 171 » » goto cleanup; |
170 } | 172 } |
171 | 173 |
172 // Should only be 1258 characters in length, but fgets will encounter th
e end of the file and stop. | 174 // Should only be 1258 characters in length, but fgets will encounter th
e end of the file and stop. |
173 char *hexcerts = fgets_strip((char *)malloc(1260), 1260, fdata); | 175 char *hexcerts = fgets_strip((char *)malloc(1260), 1260, fdata); |
174 if (!hexcerts) | 176 if (!hexcerts) |
175 { | 177 { |
176 » » LIBMTP_INFO("Error: Unable to read MTPZ certificates from ~/.mtp
z-data\n"); | 178 » » LIBMTP_ERROR("Unable to read MTPZ certificates from ~/.mtpz-data
, MTPZ disabled.\n"); |
177 » » return -1; | 179 » » goto cleanup; |
178 } | 180 } |
| 181 |
179 MTPZ_CERTIFICATES = hex_to_bytes(hexcerts, strlen(hexcerts)); | 182 MTPZ_CERTIFICATES = hex_to_bytes(hexcerts, strlen(hexcerts)); |
180 if (!MTPZ_CERTIFICATES) | 183 if (!MTPZ_CERTIFICATES) |
181 { | 184 { |
182 » » LIBMTP_INFO("Error: Unable to parse MTPZ certificates from ~/.mt
pz-data\n"); | 185 » » LIBMTP_ERROR("Unable to parse MTPZ certificates from ~/.mtpz-dat
a, MTPZ disabled.\n"); |
183 » » return -1; | 186 » » goto cleanup; |
184 } | 187 } |
185 | 188 » // If all done without errors, drop the fail |
186 » return 0; | 189 » ret = 0; |
| 190 cleanup: |
| 191 » fclose(fdata); |
| 192 » return ret; |
187 } | 193 } |
188 /* MTPZ RSA */ | 194 /* MTPZ RSA */ |
189 | 195 |
190 typedef struct mtpz_rsa_struct | 196 typedef struct mtpz_rsa_struct |
191 { | 197 { |
192 gcry_sexp_t privkey; | 198 gcry_sexp_t privkey; |
193 gcry_sexp_t pubkey; | 199 gcry_sexp_t pubkey; |
194 } mtpz_rsa_t; | 200 } mtpz_rsa_t; |
195 | 201 |
196 mtpz_rsa_t *mtpz_rsa_init(const unsigned char *modulus, const unsigned char *pri
v_key, const unsigned char *pub_exp); | 202 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... |
229 unsigned int mtpz_aes_gb11[]; | 235 unsigned int mtpz_aes_gb11[]; |
230 unsigned int mtpz_aes_gb14[]; | 236 unsigned int mtpz_aes_gb14[]; |
231 unsigned int mtpz_aes_gb13[]; | 237 unsigned int mtpz_aes_gb13[]; |
232 unsigned int mtpz_aes_gb9[]; | 238 unsigned int mtpz_aes_gb9[]; |
233 | 239 |
234 #define MTPZ_ENCRYPTIONLOBYTE(val) (((val) >> 24) & 0xFF) | 240 #define MTPZ_ENCRYPTIONLOBYTE(val) (((val) >> 24) & 0xFF) |
235 #define MTPZ_ENCRYPTIONBYTE1(val) (((val) >> 16) & 0xFF) | 241 #define MTPZ_ENCRYPTIONBYTE1(val) (((val) >> 16) & 0xFF) |
236 #define MTPZ_ENCRYPTIONBYTE2(val) (((val) >> 8) & 0xFF) | 242 #define MTPZ_ENCRYPTIONBYTE2(val) (((val) >> 8) & 0xFF) |
237 #define MTPZ_ENCRYPTIONBYTE3(val) (((val) >> 0) & 0xFF) | 243 #define MTPZ_ENCRYPTIONBYTE3(val) (((val) >> 0) & 0xFF) |
238 | 244 |
239 #define MTPZ_SWAP(x) __builtin_bswap32(x) | 245 #define MTPZ_SWAP(x) mtpz_bswap32(x) |
240 | 246 |
241 void mtpz_encryption_cipher(unsigned char *data, unsigned int len, char encrypt)
; | 247 void mtpz_encryption_cipher(unsigned char *data, unsigned int 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); | 248 void mtpz_encryption_cipher_advanced(unsigned char *key, unsigned int key_len, u
nsigned char *data, unsigned int data_len, char encrypt); |
243 unsigned char *mtpz_encryption_expand_key(unsigned char *constant, int key_len,
int count, int *out_len); | 249 unsigned char *mtpz_encryption_expand_key(unsigned char *constant, int key_len,
int count, int *out_len); |
244 void mtpz_encryption_expand_key_inner(unsigned char *constant, int key_len, unsi
gned char **out, int *out_len); | 250 void mtpz_encryption_expand_key_inner(unsigned char *constant, int key_len, unsi
gned char **out, int *out_len); |
245 void mtpz_encryption_inv_mix_columns(unsigned char *expanded, int offset, int ro
unds); | 251 void mtpz_encryption_inv_mix_columns(unsigned char *expanded, int offset, int ro
unds); |
246 void mtpz_encryption_decrypt_custom(unsigned char *data, unsigned char *seed, un
signed char *expanded); | 252 void mtpz_encryption_decrypt_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); | 253 void mtpz_encryption_encrypt_custom(unsigned char *data, unsigned char *seed, un
signed char *expanded); |
248 void mtpz_encryption_encrypt_mac(unsigned char *hash, unsigned int hash_length,
unsigned char *seed, unsigned int seed_len, unsigned char *out); | 254 void mtpz_encryption_encrypt_mac(unsigned char *hash, unsigned int hash_length,
unsigned char *seed, unsigned int seed_len, unsigned char *out); |
249 | 255 |
250 | 256 |
| 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 } |
251 | 268 |
252 | 269 |
253 /* MTPZ RSA implementation */ | 270 /* MTPZ RSA implementation */ |
254 mtpz_rsa_t *mtpz_rsa_init(const unsigned char *str_modulus, const unsigned char
*str_privkey, const unsigned char *str_pubexp) | 271 mtpz_rsa_t *mtpz_rsa_init(const unsigned char *str_modulus, const unsigned char
*str_privkey, const unsigned char *str_pubexp) |
255 { | 272 { |
256 » mtpz_rsa_t *rsa = (mtpz_rsa_t *)malloc(sizeof(mtpz_rsa_t)); | 273 » mtpz_rsa_t *rsa = calloc(1, sizeof(mtpz_rsa_t)); |
257 » memset(rsa, 0, sizeof(rsa)); | 274 » if (rsa == NULL) |
| 275 » » return NULL; |
258 | 276 |
259 gcry_mpi_t mpi_modulus, mpi_privkey, mpi_pubexp; | 277 gcry_mpi_t mpi_modulus, mpi_privkey, mpi_pubexp; |
260 | 278 |
261 gcry_mpi_scan(&mpi_modulus, GCRYMPI_FMT_HEX, str_modulus, 0, NULL); | 279 gcry_mpi_scan(&mpi_modulus, GCRYMPI_FMT_HEX, str_modulus, 0, NULL); |
262 gcry_mpi_scan(&mpi_privkey, GCRYMPI_FMT_HEX, str_privkey, 0, NULL); | 280 gcry_mpi_scan(&mpi_privkey, GCRYMPI_FMT_HEX, str_privkey, 0, NULL); |
263 gcry_mpi_scan(&mpi_pubexp, GCRYMPI_FMT_HEX, str_pubexp, 0, NULL); | 281 gcry_mpi_scan(&mpi_pubexp, GCRYMPI_FMT_HEX, str_pubexp, 0, NULL); |
264 | 282 |
265 gcry_sexp_build(&rsa->privkey, NULL, "(private-key (rsa (n %m) (e %m) (d
%m)))", mpi_modulus, mpi_pubexp, mpi_privkey); | 283 gcry_sexp_build(&rsa->privkey, NULL, "(private-key (rsa (n %m) (e %m) (d
%m)))", mpi_modulus, mpi_pubexp, mpi_privkey); |
266 gcry_sexp_build(&rsa->pubkey, NULL, "(public-key (rsa (n %m) (e %m)))",
mpi_modulus, mpi_pubexp); | 284 gcry_sexp_build(&rsa->pubkey, NULL, "(public-key (rsa (n %m) (e %m)))",
mpi_modulus, mpi_pubexp); |
267 | 285 |
(...skipping 1218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1486 }; | 1504 }; |
1487 | 1505 |
1488 static uint16_t | 1506 static uint16_t |
1489 ptp_mtpz_validatehandshakeresponse (PTPParams* params, unsigned char *random, un
signed char **calculatedHash) | 1507 ptp_mtpz_validatehandshakeresponse (PTPParams* params, unsigned char *random, un
signed char **calculatedHash) |
1490 { | 1508 { |
1491 uint16_t ret; | 1509 uint16_t ret; |
1492 unsigned int len; | 1510 unsigned int len; |
1493 unsigned char* response = NULL; | 1511 unsigned char* response = NULL; |
1494 | 1512 |
1495 ret = ptp_mtpz_getwmdrmpdappresponse (params, &response, &len); | 1513 ret = ptp_mtpz_getwmdrmpdappresponse (params, &response, &len); |
1496 » if (ret == PTP_RC_OK) | 1514 » if (ret != PTP_RC_OK) |
1497 { | 1515 { |
1498 » » char *reader = (char *)response; | 1516 » » LIBMTP_INFO ("(MTPZ) Failure - did not receive device's response
.\n"); |
1499 » » int i; | 1517 » » return ret; |
| 1518 » } |
1500 | 1519 |
1501 » » if (*(reader++) != '\x02') | 1520 » char *reader = (char *)response; |
1502 » » { | 1521 » int i; |
1503 » » » return -1; | |
1504 » » } | |
1505 | 1522 |
1506 » » if (*(reader++) != '\x02') | 1523 » if (*(reader++) != '\x02') |
1507 » » { | 1524 » { |
1508 » » » return -1; | 1525 » » return -1; |
1509 » » } | 1526 » } |
1510 | 1527 |
1511 » » // Message is always 128 bytes. | 1528 » if (*(reader++) != '\x02') |
1512 » » reader++; | 1529 » { |
1513 » » if (*(reader++) != '\x80') | 1530 » » return -1; |
1514 » » { | 1531 » } |
1515 » » » return -1; | |
1516 » » } | |
1517 | 1532 |
1518 » » char *message = (char *)malloc(128); | 1533 » // Message is always 128 bytes. |
1519 » » memcpy(message, reader, 128); | 1534 » reader++; |
1520 » » reader += 128; | 1535 » if (*(reader++) != '\x80') |
| 1536 » { |
| 1537 » » return -1; |
| 1538 » } |
1521 | 1539 |
1522 » » // Decrypt the hash-key-message.. | 1540 » char *message = (char *)malloc(128); |
1523 » » char *msg_dec = (char *)malloc(128); | 1541 » memcpy(message, reader, 128); |
1524 » » memset(msg_dec, 0, 128); | 1542 » reader += 128; |
1525 | 1543 |
1526 » » mtpz_rsa_t *rsa = mtpz_rsa_init(MTPZ_MODULUS, MTPZ_PRIVATE_KEY,
MTPZ_PUBLIC_EXPONENT); | 1544 » // Decrypt the hash-key-message.. |
1527 » » if (!rsa) | 1545 » char *msg_dec = (char *)malloc(128); |
1528 » » { | 1546 » memset(msg_dec, 0, 128); |
1529 » » » LIBMTP_INFO ("(MTPZ) Failure - could not instantiate RSA
object.\n"); | |
1530 » » » free(message); | |
1531 » » » free(msg_dec); | |
1532 » » » return -1; | |
1533 » » } | |
1534 | 1547 |
1535 » » if (mtpz_rsa_decrypt(128, (unsigned char *)message, 128, (unsign
ed char *)msg_dec, rsa) == 0) | 1548 » mtpz_rsa_t *rsa = mtpz_rsa_init(MTPZ_MODULUS, MTPZ_PRIVATE_KEY, MTPZ_PUB
LIC_EXPONENT); |
1536 » » { | 1549 » if (!rsa) |
1537 » » » LIBMTP_INFO ("(MTPZ) Failure - could not perform RSA dec
ryption.\n"); | 1550 » { |
| 1551 » » LIBMTP_INFO ("(MTPZ) Failure - could not instantiate RSA object.
\n"); |
| 1552 » » free(message); |
| 1553 » » free(msg_dec); |
| 1554 » » return -1; |
| 1555 » } |
1538 | 1556 |
1539 » » » free(message); | 1557 » if (mtpz_rsa_decrypt(128, (unsigned char *)message, 128, (unsigned char
*)msg_dec, rsa) == 0) |
1540 » » » free(msg_dec); | 1558 » { |
1541 » » » mtpz_rsa_free(rsa); | 1559 » » LIBMTP_INFO ("(MTPZ) Failure - could not perform RSA decryption.
\n"); |
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; | |
1612 | 1560 |
1613 free(message); | 1561 free(message); |
1614 free(msg_dec); | 1562 free(msg_dec); |
1615 » » free(state); | 1563 » » mtpz_rsa_free(rsa); |
1616 » » free(v10); | 1564 » » return -1; |
1617 » » free(v11); | |
1618 » » free(act_msg); | |
1619 } | 1565 } |
1620 » else | 1566 |
| 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') |
1621 { | 1587 { |
1622 » » LIBMTP_INFO ("(MTPZ) Failure - did not receive device's response
.\n"); | 1588 » » return -1; |
1623 } | 1589 } |
1624 | 1590 |
| 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 |
1625 return ret; | 1642 return ret; |
1626 } | 1643 } |
1627 | 1644 |
1628 static uint16_t | 1645 static uint16_t |
1629 ptp_mtpz_opensecuresyncsession (PTPParams* params, unsigned char *hash) | 1646 ptp_mtpz_opensecuresyncsession (PTPParams* params, unsigned char *hash) |
1630 { | 1647 { |
1631 unsigned char mch[16]; | 1648 unsigned char mch[16]; |
1632 uint32_t *hashparams = (unsigned int *)mch; | 1649 uint32_t *hashparams = (unsigned int *)mch; |
1633 unsigned int macCount = *(unsigned int *)(hash + 16); | 1650 unsigned int macCount = *(unsigned int *)(hash + 16); |
1634 uint16_t ret; | 1651 uint16_t ret; |
1635 | 1652 |
1636 mtpz_encryption_encrypt_mac(hash, 16, (unsigned char *)(&macCount), 4, m
ch); | 1653 mtpz_encryption_encrypt_mac(hash, 16, (unsigned char *)(&macCount), 4, m
ch); |
1637 | 1654 |
1638 ret = ptp_mtpz_wmdrmpd_enabletrustedfilesoperations(params, | 1655 ret = ptp_mtpz_wmdrmpd_enabletrustedfilesoperations(params, |
1639 » » __builtin_bswap32(hashparams[0]), __builtin_bswap32(hashparams[1
]), | 1656 » » MTPZ_SWAP(hashparams[0]), MTPZ_SWAP(hashparams[1]), |
1640 » » __builtin_bswap32(hashparams[2]), __builtin_bswap32(hashparams[3
])); | 1657 » » MTPZ_SWAP(hashparams[2]), MTPZ_SWAP(hashparams[3])); |
1641 return ret; | 1658 return ret; |
1642 }; | 1659 }; |
1643 | 1660 |
1644 static unsigned char * | 1661 static unsigned char * |
1645 ptp_mtpz_makeapplicationcertificatemessage (unsigned int *out_len, unsigned char
**out_random) | 1662 ptp_mtpz_makeapplicationcertificatemessage (unsigned int *out_len, unsigned char
**out_random) |
1646 { | 1663 { |
1647 *out_len = 785; | 1664 *out_len = 785; |
1648 | 1665 |
1649 unsigned char *acm = (unsigned char *)malloc(785); | 1666 unsigned char *acm = (unsigned char *)malloc(785); |
1650 unsigned char *target = acm; | 1667 unsigned char *target = acm; |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1805 free (message); | 1822 free (message); |
1806 | 1823 |
1807 LIBMTP_INFO ("(MTPZ) Opening secure sync session.\n"); | 1824 LIBMTP_INFO ("(MTPZ) Opening secure sync session.\n"); |
1808 ret = ptp_mtpz_opensecuresyncsession(params, hash); | 1825 ret = ptp_mtpz_opensecuresyncsession(params, hash); |
1809 free_hash: | 1826 free_hash: |
1810 free(hash); | 1827 free(hash); |
1811 free_random: | 1828 free_random: |
1812 free(random); | 1829 free(random); |
1813 return ret; | 1830 return ret; |
1814 } | 1831 } |
OLD | NEW |