Permalink
Browse files

Made dfu-util more flexible, corrected dmg SHA-1 problem under 64-bit…

… platforms
  • Loading branch information...
1 parent f23cc99 commit 35b51a01b0f1a0a711896000d8aa7e2660fc2faf @planetbeing committed May 2, 2009
Showing with 44 additions and 39 deletions.
  1. +1 −1 CMakeLists.txt
  2. +3 −1 dfu-util/main.c
  3. +33 −31 dmg/checksum.c
  4. +7 −6 includes/dmg/dmg.h
View
2 CMakeLists.txt
@@ -41,7 +41,7 @@ SET(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README.markdown")
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
SET(CPACK_PACKAGE_VERSION_MAJOR "0")
SET(CPACK_PACKAGE_VERSION_MINOR "5")
-SET(CPACK_PACKAGE_VERSION_PATCH "7")
+SET(CPACK_PACKAGE_VERSION_PATCH "8")
SET(CPACK_PACKAGE_EXECUTABLES "xpwn" "XPwn Pwner")
SET(CPACK_PACKAGE_EXECUTABLES "ipsw" "IPSW Tool")
SET(CPACK_PACKAGE_EXECUTABLES "hdutil" "Apple disk image utility")
View
4 dfu-util/main.c
@@ -66,6 +66,7 @@ struct usb_vendprod {
struct dfu_if {
uint16_t vendor;
uint16_t product;
+ uint16_t product_mask;
uint8_t configuration;
uint8_t interface;
uint8_t altsetting;
@@ -241,7 +242,7 @@ static int iterate_dfu_devices(struct dfu_if *dif,
if (dif && (dif->flags &
(DFU_IFF_VENDOR|DFU_IFF_PRODUCT)) &&
(dev->descriptor.idVendor != dif->vendor ||
- dev->descriptor.idProduct != dif->product))
+ (dev->descriptor.idProduct & dif->product_mask) != (dif->product & dif->product_mask)))
continue;
if (dif && (dif->flags & DFU_IFF_DEVNUM) &&
(atoi(usb_bus->dirname) != dif->bus ||
@@ -337,6 +338,7 @@ int download(AbstractFile* file, unsigned int transfer_size, int final_reset)
dif->flags = DFU_IFF_VENDOR | DFU_IFF_PRODUCT;
dif->vendor = 0x05ac;
dif->product = 0x1222;
+ dif->product_mask = 0xfff0;
usb_init();
//usb_set_debug(255);
View
64 dmg/checksum.c
@@ -168,16 +168,17 @@ A million repetitions of "a"
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
-#define SHA1HANDSOFF * Copies data before messing with it.
+#define SHA1HANDSOFF
+
+void SHA1Transform(uint32_t state[5], const uint8_t buffer[64]);
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
-
+/* FIXME: can we do this in an endian-proof way? */
#define blk0(i) ((endianness == IS_LITTLE_ENDIAN) ? (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
- |(rol(block->l[i],8)&0x00FF00FF)) : block->l[i])
-
+ |(rol(block->l[i],8)&0x00FF00FF)) : block->l[i])
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))
@@ -188,30 +189,31 @@ A million repetitions of "a"
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
-
/* Hash a single 512-bit block. This is the core of the algorithm. */
-
-void SHA1Transform(unsigned long state[5], const unsigned char buffer[64])
+void SHA1Transform(uint32_t state[5], const uint8_t buffer[64])
{
-unsigned long a, b, c, d, e;
-typedef union {
- unsigned char c[64];
- unsigned long l[16];
-} CHAR64LONG16;
-CHAR64LONG16* block;
+ uint32_t a, b, c, d, e;
+ typedef union {
+ uint8_t c[64];
+ uint32_t l[16];
+ } CHAR64LONG16;
+ CHAR64LONG16* block;
+
#ifdef SHA1HANDSOFF
-static unsigned char workspace[64];
+ static uint8_t workspace[64];
block = (CHAR64LONG16*)workspace;
memcpy(block, buffer, 64);
#else
block = (CHAR64LONG16*)buffer;
#endif
+
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
+
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
@@ -233,19 +235,20 @@ static unsigned char workspace[64];
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
+
/* Wipe variables */
a = b = c = d = e = 0;
}
/* SHA1Init - Initialize new context */
-
void SHA1Init(SHA1_CTX* context)
{
/* SHA1 initialization constants */
@@ -259,10 +262,9 @@ void SHA1Init(SHA1_CTX* context)
/* Run your data through this. */
-
-void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len)
+void SHA1Update(SHA1_CTX* context, const uint8_t* data, const size_t len)
{
-unsigned int i, j;
+ size_t i, j;
j = (context->count[0] >> 3) & 63;
if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
@@ -271,7 +273,7 @@ unsigned int i, j;
memcpy(&context->buffer[j], data, (i = 64-j));
SHA1Transform(context->state, context->buffer);
for ( ; i + 63 < len; i += 64) {
- SHA1Transform(context->state, &data[i]);
+ SHA1Transform(context->state, data + i);
}
j = 0;
}
@@ -281,33 +283,33 @@ unsigned int i, j;
/* Add padding and return the message digest. */
-
-void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
+void SHA1Final(uint8_t digest[SHA1_DIGEST_SIZE], SHA1_CTX* context)
{
-unsigned long i, j;
-unsigned char finalcount[8];
+ uint32_t i;
+ uint8_t finalcount[8];
for (i = 0; i < 8; i++) {
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
}
- SHA1Update(context, (unsigned char *)"\200", 1);
+ SHA1Update(context, (uint8_t *)"\200", 1);
while ((context->count[0] & 504) != 448) {
- SHA1Update(context, (unsigned char *)"\0", 1);
+ SHA1Update(context, (uint8_t *)"\0", 1);
}
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
- for (i = 0; i < 20; i++) {
- digest[i] = (unsigned char)
+ for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
+ digest[i] = (uint8_t)
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
}
+
/* Wipe variables */
- i = j = 0;
+ i = 0;
memset(context->buffer, 0, 64);
memset(context->state, 0, 20);
memset(context->count, 0, 8);
- memset(&finalcount, 0, 8);
-#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
+ memset(finalcount, 0, 8); /* SWR */
+
+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
SHA1Transform(context->state, context->buffer);
#endif
}
-
View
13 includes/dmg/dmg.h
@@ -229,10 +229,12 @@ typedef struct ResourceKey {
FlipDataFunc flipData;
} ResourceKey;
+#define SHA1_DIGEST_SIZE 20
+
typedef struct {
- unsigned long state[5];
- unsigned long count[2];
- unsigned char buffer[64];
+ uint32_t state[5];
+ uint32_t count[2];
+ uint8_t buffer[64];
} SHA1_CTX;
typedef struct {
@@ -283,10 +285,9 @@ extern "C" {
void BlockCRC(void* token, const unsigned char* data, size_t len);
void CRCProxy(void* token, const unsigned char* data, size_t len);
- void SHA1Transform(unsigned long state[5], const unsigned char buffer[64]);
void SHA1Init(SHA1_CTX* context);
- void SHA1Update(SHA1_CTX* context, const unsigned char* data, unsigned int len);
- void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
+ void SHA1Update(SHA1_CTX* context, const uint8_t* data, const size_t len);
+ void SHA1Final(uint8_t digest[SHA1_DIGEST_SIZE], SHA1_CTX* context);
void flipUDIFChecksum(UDIFChecksum* o, char out);
void readUDIFChecksum(AbstractFile* file, UDIFChecksum* o);

0 comments on commit 35b51a0

Please sign in to comment.