A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd

ipodpatcher: Split executable only parts out.

Allow building both as library and executable at the same time.

Change-Id: Idc40354fdedaeace727043936352fc17232bf16e

+409 -355
+11
utils/CMakeLists.txt
··· 82 82 endif() 83 83 84 84 85 + add_executable(ipodpatcher-bin 86 + ipodpatcher/main.c 87 + ipodpatcher/ipodpatcher-aupd.c 88 + ) 89 + target_link_libraries(ipodpatcher-bin ipodpatcher) 90 + target_compile_definitions(ipodpatcher-bin PRIVATE VERSION="none") 91 + set_target_properties(ipodpatcher-bin PROPERTIES OUTPUT_NAME ipodpatcher) 92 + if(APPLE) 93 + target_link_libraries(ipodpatcher-bin ${FRAMEWORK_IOKIT} ${FRAMEWORK_COREFOUNDATION}) 94 + endif() 95 + 85 96 add_library(ipodpatcher 86 97 ipodpatcher/arc4.h 87 98 ipodpatcher/arc4.c
+398
utils/ipodpatcher/ipodpatcher-aupd.c
··· 1 + /*************************************************************************** 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 + * $Id$ 9 + * 10 + * Copyright (C) 2006-2007 Dave Chapman 11 + * 12 + * This program is free software; you can redistribute it and/or 13 + * modify it under the terms of the GNU General Public License 14 + * as published by the Free Software Foundation; either version 2 15 + * of the License, or (at your option) any later version. 16 + * 17 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 + * KIND, either express or implied. 19 + * 20 + ****************************************************************************/ 21 + 22 + #include <stdio.h> 23 + #include <unistd.h> 24 + #include <fcntl.h> 25 + #include <string.h> 26 + #include <stdlib.h> 27 + #include <inttypes.h> 28 + #include <stdbool.h> 29 + #include <sys/types.h> 30 + #include <sys/stat.h> 31 + 32 + #include "ipodpatcher.h" 33 + 34 + #include "arc4.h" 35 + 36 + static inline int le2int(unsigned char* buf) 37 + { 38 + int32_t res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; 39 + 40 + return res; 41 + } 42 + 43 + static inline void int2le(unsigned int val, unsigned char* addr) 44 + { 45 + addr[0] = val & 0xFF; 46 + addr[1] = (val >> 8) & 0xff; 47 + addr[2] = (val >> 16) & 0xff; 48 + addr[3] = (val >> 24) & 0xff; 49 + } 50 + 51 + static inline uint32_t getuint32le(unsigned char* buf) 52 + { 53 + int32_t res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; 54 + 55 + return res; 56 + } 57 + 58 + /* testMarker and GetSecurityBlockKey based on code from BadBlocks and 59 + Kingstone, posted at http://ipodlinux.org/Flash_Decryption 60 + 61 + */ 62 + 63 + static bool testMarker(int marker) 64 + { 65 + int mask, decrypt, temp1, temp2; 66 + 67 + mask = (marker&0xff)|((marker&0xff)<<8)|((marker&0xff)<<16)|((marker&0xff)<<24); 68 + decrypt = marker ^ mask; 69 + temp1=(int)((unsigned int)decrypt>>24); 70 + temp2=decrypt<<8; 71 + 72 + if (temp1==0) 73 + return false; 74 + 75 + temp2=(int)((unsigned int)temp2>>24); 76 + decrypt=decrypt<<16; 77 + decrypt=(int)((unsigned int)decrypt>>24); 78 + 79 + if ((temp1 < temp2) && (temp2 < decrypt)) 80 + { 81 + temp1 = temp1 & 0xf; 82 + temp2 = temp2 & 0xf; 83 + decrypt = decrypt & 0xf; 84 + 85 + if ((temp1 > temp2) && (temp2 > decrypt) && (decrypt != 0)) 86 + { 87 + return true; 88 + } 89 + } 90 + return false; 91 + } 92 + 93 + static int GetSecurityBlockKey(unsigned char *data, unsigned char* this_key) 94 + { 95 + int constant = 0x54c3a298; 96 + int key=0; 97 + int nkeys = 0; 98 + int aMarker=0; 99 + int pos=0; 100 + int c, count; 101 + int temp1; 102 + static const int offset[8]={0x5,0x25,0x6f,0x69,0x15,0x4d,0x40,0x34}; 103 + 104 + for (c = 0; c < 8; c++) 105 + { 106 + pos = offset[c]*4; 107 + aMarker = getuint32le(data + pos); 108 + 109 + if (testMarker(aMarker)) 110 + { 111 + if (c<7) 112 + pos =(offset[c+1]*4)+4; 113 + else 114 + pos =(offset[0]*4)+4; 115 + 116 + key=0; 117 + 118 + temp1=aMarker; 119 + 120 + for (count=0;count<2;count++){ 121 + int word = getuint32le(data + pos); 122 + temp1 = aMarker; 123 + temp1 = temp1^word; 124 + temp1 = temp1^constant; 125 + key = temp1; 126 + pos = pos+4; 127 + } 128 + int r1=0x6f; 129 + int r2=0; 130 + int r12; 131 + int r14; 132 + unsigned int r_tmp; 133 + 134 + for (count=2;count<128;count=count+2){ 135 + r2=getuint32le(data+count*4); 136 + r12=getuint32le(data+(count*4)+4); 137 + r_tmp=(unsigned int)r12>>16; 138 + r14=r2 | ((int)r_tmp); 139 + r2=r2&0xffff; 140 + r2=r2 | r12; 141 + r1=r1^r14; 142 + r1=r1+r2; 143 + } 144 + key=key^r1; 145 + 146 + // Invert key, little endian 147 + this_key[0] = key & 0xff; 148 + this_key[1] = (key >> 8) & 0xff; 149 + this_key[2] = (key >> 16) & 0xff; 150 + this_key[3] = (key >> 24) & 0xff; 151 + nkeys++; 152 + } 153 + } 154 + return nkeys; 155 + } 156 + 157 + static int find_key(struct ipod_t* ipod, int aupd, unsigned char* key) 158 + { 159 + int n; 160 + 161 + /* Firstly read the security block and find the RC4 key. This is 162 + in the sector preceeding the AUPD image. */ 163 + 164 + if(ipod->sectorbuf == NULL) { 165 + fprintf(stderr,"[ERR] Buffer not initialized."); 166 + return -1; 167 + } 168 + fprintf(stderr, "[INFO] Reading security block at offset 0x%08x\n",ipod->ipod_directory[aupd].devOffset-ipod->sector_size); 169 + if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset-ipod->sector_size) < 0) { 170 + return -1; 171 + } 172 + 173 + if ((n = ipod_read(ipod, 512)) < 0) { 174 + return -1; 175 + } 176 + 177 + n = GetSecurityBlockKey(ipod->sectorbuf, key); 178 + 179 + if (n != 1) 180 + { 181 + fprintf(stderr, "[ERR] %d keys found in security block, can not continue\n",n); 182 + return -1; 183 + } 184 + 185 + return 0; 186 + } 187 + 188 + int read_aupd(struct ipod_t* ipod, char* filename) 189 + { 190 + int length; 191 + int i; 192 + int outfile; 193 + int n; 194 + int aupd; 195 + struct rc4_key_t rc4; 196 + unsigned char key[4]; 197 + unsigned long chksum=0; 198 + 199 + if(ipod->sectorbuf == NULL) { 200 + fprintf(stderr,"[ERR] Buffer not initialized."); 201 + return -1; 202 + } 203 + aupd = 0; 204 + while ((aupd < ipod->nimages) && (ipod->ipod_directory[aupd].ftype != FTYPE_AUPD)) 205 + { 206 + aupd++; 207 + } 208 + 209 + if (aupd == ipod->nimages) 210 + { 211 + fprintf(stderr,"[ERR] No AUPD image in firmware partition.\n"); 212 + return -1; 213 + } 214 + 215 + length = ipod->ipod_directory[aupd].len; 216 + 217 + fprintf(stderr,"[INFO] Reading firmware (%d bytes)\n",length); 218 + 219 + if (find_key(ipod, aupd, key) < 0) 220 + { 221 + return -1; 222 + } 223 + 224 + fprintf(stderr, "[INFO] Decrypting AUPD image with key %02x%02x%02x%02x\n",key[0],key[1],key[2],key[3]); 225 + 226 + if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset) < 0) { 227 + return -1; 228 + } 229 + 230 + i = (length+ipod->sector_size-1) & ~(ipod->sector_size-1); 231 + 232 + if ((n = ipod_read(ipod,i)) < 0) { 233 + return -1; 234 + } 235 + 236 + if (n < i) { 237 + fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n", 238 + i,n); 239 + return -1; 240 + } 241 + 242 + /* Perform the decryption - this is standard (A)RC4 */ 243 + matrixArc4Init(&rc4, key, 4); 244 + matrixArc4(&rc4, ipod->sectorbuf, ipod->sectorbuf, length); 245 + 246 + chksum = 0; 247 + for (i = 0; i < (int)length; i++) { 248 + /* add 8 unsigned bits but keep a 32 bit sum */ 249 + chksum += ipod->sectorbuf[i]; 250 + } 251 + 252 + if (chksum != ipod->ipod_directory[aupd].chksum) 253 + { 254 + fprintf(stderr,"[ERR] Decryption failed - checksum error\n"); 255 + return -1; 256 + } 257 + fprintf(stderr,"[INFO] Decrypted OK (checksum matches header)\n"); 258 + 259 + outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666); 260 + if (outfile < 0) { 261 + fprintf(stderr,"[ERR] Couldn't open file %s\n",filename); 262 + return -1; 263 + } 264 + 265 + n = write(outfile,ipod->sectorbuf,length); 266 + if (n != length) { 267 + fprintf(stderr,"[ERR] Write error - %d\n",n); 268 + } 269 + close(outfile); 270 + 271 + return 0; 272 + } 273 + 274 + int write_aupd(struct ipod_t* ipod, char* filename) 275 + { 276 + unsigned int length; 277 + int i; 278 + int x; 279 + int n; 280 + int infile; 281 + int newsize; 282 + int aupd; 283 + unsigned long chksum=0; 284 + struct rc4_key_t rc4; 285 + unsigned char key[4]; 286 + 287 + if(ipod->sectorbuf == NULL) { 288 + fprintf(stderr,"[ERR] Buffer not initialized."); 289 + return -1; 290 + } 291 + /* First check that the input file is the correct type for this ipod. */ 292 + infile=open(filename,O_RDONLY); 293 + if (infile < 0) { 294 + fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename); 295 + return -1; 296 + } 297 + 298 + length = filesize(infile); 299 + newsize=(length+ipod->sector_size-1)&~(ipod->sector_size-1); 300 + 301 + fprintf(stderr,"[INFO] Padding input file from 0x%08x to 0x%08x bytes\n", 302 + length,newsize); 303 + 304 + if (newsize > BUFFER_SIZE) { 305 + fprintf(stderr,"[ERR] Input file too big for buffer\n"); 306 + if (infile >= 0) close(infile); 307 + return -1; 308 + } 309 + 310 + /* Find aupd image number */ 311 + aupd = 0; 312 + while ((aupd < ipod->nimages) && (ipod->ipod_directory[aupd].ftype != FTYPE_AUPD)) 313 + { 314 + aupd++; 315 + } 316 + 317 + if (aupd == ipod->nimages) 318 + { 319 + fprintf(stderr,"[ERR] No AUPD image in firmware partition.\n"); 320 + return -1; 321 + } 322 + 323 + if (length != ipod->ipod_directory[aupd].len) 324 + { 325 + fprintf(stderr,"[ERR] AUPD image (%d bytes) differs in size to %s (%d bytes).\n", 326 + ipod->ipod_directory[aupd].len, filename, length); 327 + return -1; 328 + } 329 + 330 + if (find_key(ipod, aupd, key) < 0) 331 + { 332 + return -1; 333 + } 334 + 335 + fprintf(stderr, "[INFO] Encrypting AUPD image with key %02x%02x%02x%02x\n",key[0],key[1],key[2],key[3]); 336 + 337 + /* We now know we have enough space, so write it. */ 338 + 339 + fprintf(stderr,"[INFO] Reading input file...\n"); 340 + n = read(infile,ipod->sectorbuf,length); 341 + if (n < 0) { 342 + fprintf(stderr,"[ERR] Couldn't read input file\n"); 343 + close(infile); 344 + return -1; 345 + } 346 + close(infile); 347 + 348 + /* Pad the data with zeros */ 349 + memset(ipod->sectorbuf+length,0,newsize-length); 350 + 351 + /* Calculate the new checksum (before we encrypt) */ 352 + chksum = 0; 353 + for (i = 0; i < (int)length; i++) { 354 + /* add 8 unsigned bits but keep a 32 bit sum */ 355 + chksum += ipod->sectorbuf[i]; 356 + } 357 + 358 + /* Perform the encryption - this is standard (A)RC4 */ 359 + matrixArc4Init(&rc4, key, 4); 360 + matrixArc4(&rc4, ipod->sectorbuf, ipod->sectorbuf, length); 361 + 362 + if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset) < 0) { 363 + fprintf(stderr,"[ERR] Seek failed\n"); 364 + return -1; 365 + } 366 + 367 + if ((n = ipod_write(ipod,newsize)) < 0) { 368 + perror("[ERR] Write failed\n"); 369 + return -1; 370 + } 371 + 372 + if (n < newsize) { 373 + fprintf(stderr,"[ERR] Short write - requested %d bytes, received %d\n" 374 + ,newsize,n); 375 + return -1; 376 + } 377 + fprintf(stderr,"[INFO] Wrote %d bytes to firmware partition\n",n); 378 + 379 + x = ipod->diroffset % ipod->sector_size; 380 + 381 + /* Read directory */ 382 + if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } 383 + 384 + n=ipod_read(ipod, ipod->sector_size); 385 + if (n < 0) { return -1; } 386 + 387 + /* Update checksum */ 388 + fprintf(stderr,"[INFO] Updating checksum to 0x%08x (was 0x%08x)\n",(unsigned int)chksum,le2int(ipod->sectorbuf + x + aupd*40 + 28)); 389 + int2le(chksum,ipod->sectorbuf+x+aupd*40+28); 390 + 391 + /* Write directory */ 392 + if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } 393 + n=ipod_write(ipod, ipod->sector_size); 394 + if (n < 0) { return -1; } 395 + 396 + return 0; 397 + } 398 +
-355
utils/ipodpatcher/ipodpatcher.c
··· 45 45 #include "ipodnano2g.h" 46 46 #endif 47 47 48 - #ifndef RBUTIL 49 - #include "arc4.h" 50 - #endif 51 - 52 48 int ipod_verbose = 0; 53 49 54 50 ··· 1997 1993 } 1998 1994 } 1999 1995 2000 - #ifndef RBUTIL 2001 - 2002 - static inline uint32_t getuint32le(unsigned char* buf) 2003 - { 2004 - int32_t res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; 2005 - 2006 - return res; 2007 - } 2008 - 2009 - /* testMarker and GetSecurityBlockKey based on code from BadBlocks and 2010 - Kingstone, posted at http://ipodlinux.org/Flash_Decryption 2011 - 2012 - */ 2013 - 2014 - static bool testMarker(int marker) 2015 - { 2016 - int mask, decrypt, temp1, temp2; 2017 - 2018 - mask = (marker&0xff)|((marker&0xff)<<8)|((marker&0xff)<<16)|((marker&0xff)<<24); 2019 - decrypt = marker ^ mask; 2020 - temp1=(int)((unsigned int)decrypt>>24); 2021 - temp2=decrypt<<8; 2022 - 2023 - if (temp1==0) 2024 - return false; 2025 - 2026 - temp2=(int)((unsigned int)temp2>>24); 2027 - decrypt=decrypt<<16; 2028 - decrypt=(int)((unsigned int)decrypt>>24); 2029 - 2030 - if ((temp1 < temp2) && (temp2 < decrypt)) 2031 - { 2032 - temp1 = temp1 & 0xf; 2033 - temp2 = temp2 & 0xf; 2034 - decrypt = decrypt & 0xf; 2035 - 2036 - if ((temp1 > temp2) && (temp2 > decrypt) && (decrypt != 0)) 2037 - { 2038 - return true; 2039 - } 2040 - } 2041 - return false; 2042 - } 2043 - 2044 - static int GetSecurityBlockKey(unsigned char *data, unsigned char* this_key) 2045 - { 2046 - int constant = 0x54c3a298; 2047 - int key=0; 2048 - int nkeys = 0; 2049 - int aMarker=0; 2050 - int pos=0; 2051 - int c, count; 2052 - int temp1; 2053 - static const int offset[8]={0x5,0x25,0x6f,0x69,0x15,0x4d,0x40,0x34}; 2054 - 2055 - for (c = 0; c < 8; c++) 2056 - { 2057 - pos = offset[c]*4; 2058 - aMarker = getuint32le(data + pos); 2059 - 2060 - if (testMarker(aMarker)) 2061 - { 2062 - if (c<7) 2063 - pos =(offset[c+1]*4)+4; 2064 - else 2065 - pos =(offset[0]*4)+4; 2066 - 2067 - key=0; 2068 - 2069 - temp1=aMarker; 2070 - 2071 - for (count=0;count<2;count++){ 2072 - int word = getuint32le(data + pos); 2073 - temp1 = aMarker; 2074 - temp1 = temp1^word; 2075 - temp1 = temp1^constant; 2076 - key = temp1; 2077 - pos = pos+4; 2078 - } 2079 - int r1=0x6f; 2080 - int r2=0; 2081 - int r12; 2082 - int r14; 2083 - unsigned int r_tmp; 2084 - 2085 - for (count=2;count<128;count=count+2){ 2086 - r2=getuint32le(data+count*4); 2087 - r12=getuint32le(data+(count*4)+4); 2088 - r_tmp=(unsigned int)r12>>16; 2089 - r14=r2 | ((int)r_tmp); 2090 - r2=r2&0xffff; 2091 - r2=r2 | r12; 2092 - r1=r1^r14; 2093 - r1=r1+r2; 2094 - } 2095 - key=key^r1; 2096 - 2097 - // Invert key, little endian 2098 - this_key[0] = key & 0xff; 2099 - this_key[1] = (key >> 8) & 0xff; 2100 - this_key[2] = (key >> 16) & 0xff; 2101 - this_key[3] = (key >> 24) & 0xff; 2102 - nkeys++; 2103 - } 2104 - } 2105 - return nkeys; 2106 - } 2107 - 2108 - static int find_key(struct ipod_t* ipod, int aupd, unsigned char* key) 2109 - { 2110 - int n; 2111 - 2112 - /* Firstly read the security block and find the RC4 key. This is 2113 - in the sector preceeding the AUPD image. */ 2114 - 2115 - if(ipod->sectorbuf == NULL) { 2116 - fprintf(stderr,"[ERR] Buffer not initialized."); 2117 - return -1; 2118 - } 2119 - fprintf(stderr, "[INFO] Reading security block at offset 0x%08x\n",ipod->ipod_directory[aupd].devOffset-ipod->sector_size); 2120 - if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset-ipod->sector_size) < 0) { 2121 - return -1; 2122 - } 2123 - 2124 - if ((n = ipod_read(ipod, 512)) < 0) { 2125 - return -1; 2126 - } 2127 - 2128 - n = GetSecurityBlockKey(ipod->sectorbuf, key); 2129 - 2130 - if (n != 1) 2131 - { 2132 - fprintf(stderr, "[ERR] %d keys found in security block, can not continue\n",n); 2133 - return -1; 2134 - } 2135 - 2136 - return 0; 2137 - } 2138 - 2139 - int read_aupd(struct ipod_t* ipod, char* filename) 2140 - { 2141 - int length; 2142 - int i; 2143 - int outfile; 2144 - int n; 2145 - int aupd; 2146 - struct rc4_key_t rc4; 2147 - unsigned char key[4]; 2148 - unsigned long chksum=0; 2149 - 2150 - if(ipod->sectorbuf == NULL) { 2151 - fprintf(stderr,"[ERR] Buffer not initialized."); 2152 - return -1; 2153 - } 2154 - aupd = 0; 2155 - while ((aupd < ipod->nimages) && (ipod->ipod_directory[aupd].ftype != FTYPE_AUPD)) 2156 - { 2157 - aupd++; 2158 - } 2159 - 2160 - if (aupd == ipod->nimages) 2161 - { 2162 - fprintf(stderr,"[ERR] No AUPD image in firmware partition.\n"); 2163 - return -1; 2164 - } 2165 - 2166 - length = ipod->ipod_directory[aupd].len; 2167 - 2168 - fprintf(stderr,"[INFO] Reading firmware (%d bytes)\n",length); 2169 - 2170 - if (find_key(ipod, aupd, key) < 0) 2171 - { 2172 - return -1; 2173 - } 2174 - 2175 - fprintf(stderr, "[INFO] Decrypting AUPD image with key %02x%02x%02x%02x\n",key[0],key[1],key[2],key[3]); 2176 - 2177 - if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset) < 0) { 2178 - return -1; 2179 - } 2180 - 2181 - i = (length+ipod->sector_size-1) & ~(ipod->sector_size-1); 2182 - 2183 - if ((n = ipod_read(ipod,i)) < 0) { 2184 - return -1; 2185 - } 2186 - 2187 - if (n < i) { 2188 - fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n", 2189 - i,n); 2190 - return -1; 2191 - } 2192 - 2193 - /* Perform the decryption - this is standard (A)RC4 */ 2194 - matrixArc4Init(&rc4, key, 4); 2195 - matrixArc4(&rc4, ipod->sectorbuf, ipod->sectorbuf, length); 2196 - 2197 - chksum = 0; 2198 - for (i = 0; i < (int)length; i++) { 2199 - /* add 8 unsigned bits but keep a 32 bit sum */ 2200 - chksum += ipod->sectorbuf[i]; 2201 - } 2202 - 2203 - if (chksum != ipod->ipod_directory[aupd].chksum) 2204 - { 2205 - fprintf(stderr,"[ERR] Decryption failed - checksum error\n"); 2206 - return -1; 2207 - } 2208 - fprintf(stderr,"[INFO] Decrypted OK (checksum matches header)\n"); 2209 - 2210 - outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666); 2211 - if (outfile < 0) { 2212 - fprintf(stderr,"[ERR] Couldn't open file %s\n",filename); 2213 - return -1; 2214 - } 2215 - 2216 - n = write(outfile,ipod->sectorbuf,length); 2217 - if (n != length) { 2218 - fprintf(stderr,"[ERR] Write error - %d\n",n); 2219 - } 2220 - close(outfile); 2221 - 2222 - return 0; 2223 - } 2224 - 2225 - int write_aupd(struct ipod_t* ipod, char* filename) 2226 - { 2227 - unsigned int length; 2228 - int i; 2229 - int x; 2230 - int n; 2231 - int infile; 2232 - int newsize; 2233 - int aupd; 2234 - unsigned long chksum=0; 2235 - struct rc4_key_t rc4; 2236 - unsigned char key[4]; 2237 - 2238 - if(ipod->sectorbuf == NULL) { 2239 - fprintf(stderr,"[ERR] Buffer not initialized."); 2240 - return -1; 2241 - } 2242 - /* First check that the input file is the correct type for this ipod. */ 2243 - infile=open(filename,O_RDONLY); 2244 - if (infile < 0) { 2245 - fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename); 2246 - return -1; 2247 - } 2248 - 2249 - length = filesize(infile); 2250 - newsize=(length+ipod->sector_size-1)&~(ipod->sector_size-1); 2251 - 2252 - fprintf(stderr,"[INFO] Padding input file from 0x%08x to 0x%08x bytes\n", 2253 - length,newsize); 2254 - 2255 - if (newsize > BUFFER_SIZE) { 2256 - fprintf(stderr,"[ERR] Input file too big for buffer\n"); 2257 - if (infile >= 0) close(infile); 2258 - return -1; 2259 - } 2260 - 2261 - /* Find aupd image number */ 2262 - aupd = 0; 2263 - while ((aupd < ipod->nimages) && (ipod->ipod_directory[aupd].ftype != FTYPE_AUPD)) 2264 - { 2265 - aupd++; 2266 - } 2267 - 2268 - if (aupd == ipod->nimages) 2269 - { 2270 - fprintf(stderr,"[ERR] No AUPD image in firmware partition.\n"); 2271 - return -1; 2272 - } 2273 - 2274 - if (length != ipod->ipod_directory[aupd].len) 2275 - { 2276 - fprintf(stderr,"[ERR] AUPD image (%d bytes) differs in size to %s (%d bytes).\n", 2277 - ipod->ipod_directory[aupd].len, filename, length); 2278 - return -1; 2279 - } 2280 - 2281 - if (find_key(ipod, aupd, key) < 0) 2282 - { 2283 - return -1; 2284 - } 2285 - 2286 - fprintf(stderr, "[INFO] Encrypting AUPD image with key %02x%02x%02x%02x\n",key[0],key[1],key[2],key[3]); 2287 - 2288 - /* We now know we have enough space, so write it. */ 2289 - 2290 - fprintf(stderr,"[INFO] Reading input file...\n"); 2291 - n = read(infile,ipod->sectorbuf,length); 2292 - if (n < 0) { 2293 - fprintf(stderr,"[ERR] Couldn't read input file\n"); 2294 - close(infile); 2295 - return -1; 2296 - } 2297 - close(infile); 2298 - 2299 - /* Pad the data with zeros */ 2300 - memset(ipod->sectorbuf+length,0,newsize-length); 2301 - 2302 - /* Calculate the new checksum (before we encrypt) */ 2303 - chksum = 0; 2304 - for (i = 0; i < (int)length; i++) { 2305 - /* add 8 unsigned bits but keep a 32 bit sum */ 2306 - chksum += ipod->sectorbuf[i]; 2307 - } 2308 - 2309 - /* Perform the encryption - this is standard (A)RC4 */ 2310 - matrixArc4Init(&rc4, key, 4); 2311 - matrixArc4(&rc4, ipod->sectorbuf, ipod->sectorbuf, length); 2312 - 2313 - if (ipod_seek(ipod, ipod->fwoffset+ipod->ipod_directory[aupd].devOffset) < 0) { 2314 - fprintf(stderr,"[ERR] Seek failed\n"); 2315 - return -1; 2316 - } 2317 - 2318 - if ((n = ipod_write(ipod,newsize)) < 0) { 2319 - perror("[ERR] Write failed\n"); 2320 - return -1; 2321 - } 2322 - 2323 - if (n < newsize) { 2324 - fprintf(stderr,"[ERR] Short write - requested %d bytes, received %d\n" 2325 - ,newsize,n); 2326 - return -1; 2327 - } 2328 - fprintf(stderr,"[INFO] Wrote %d bytes to firmware partition\n",n); 2329 - 2330 - x = ipod->diroffset % ipod->sector_size; 2331 - 2332 - /* Read directory */ 2333 - if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } 2334 - 2335 - n=ipod_read(ipod, ipod->sector_size); 2336 - if (n < 0) { return -1; } 2337 - 2338 - /* Update checksum */ 2339 - fprintf(stderr,"[INFO] Updating checksum to 0x%08x (was 0x%08x)\n",(unsigned int)chksum,le2int(ipod->sectorbuf + x + aupd*40 + 28)); 2340 - int2le(chksum,ipod->sectorbuf+x+aupd*40+28); 2341 - 2342 - /* Write directory */ 2343 - if (ipod_seek(ipod, ipod->start + ipod->diroffset - x) < 0) { return -1; } 2344 - n=ipod_write(ipod, ipod->sector_size); 2345 - if (n < 0) { return -1; } 2346 - 2347 - return 0; 2348 - } 2349 - 2350 - #endif