diff -urpN 179-b/src/loader.c 179-a/src/loader.c --- 179-b/src/loader.c 2013-01-30 16:47:11.535000000 -0600 +++ 179-a/src/loader.c 2013-02-01 06:58:31.352783700 -0600 @@ -695,6 +695,138 @@ static void ldr_init_salts(struct db_mai } } +/* #define DEBUG_SALT_SORT */ + +/* + * this will be the salt_compare() method we stick into + * wpapsk_fmt.c (and cuda/opencl) + */ +int salt_compare(const void *x, const void *y) +{ + /* this is all that is needed in wpapsk salt_compare() */ + return strncmp((const char*)x, (const char*)y, 36); +} + +/* + * This was done as a structure to allow more data to be + * placed into it, beyond just the simple pointer. The + * pointer is really all that is needed. However, when + * building with the structure containing just a pointer, + * we get no (or very little) degredation over just an + * array of pointers. The compiler treats them the same. + * so for ease of debugging, I have left this as a simple + * structure + */ +typedef struct salt_cmp_s +{ + struct db_salt *p; +#ifdef DEBUG_SALT_SORT + /* used by JimF in debugging. Left in for now */ + int org_idx; + char str[36]; +#endif +} salt_cmp_t; + +/* + * there is no way to pass this pointer to the sort function, so + * we set it before calling sort. Right now, we do not use it, + * but later we will use salt_sort_db->format->methods.salt_compare() + * we actually could just harvest off the function pointer to the + * salt_compare function, instead (TBD), instead of the db_main* + */ +static struct db_main *salt_sort_db; + +/* + * This helper function will stay in loader. It is what the qsort + * function calls. This function is smart enough to know how to + * parse a salt_cmp_t. It does that, to find the real salt values, + * and then calls the formats salt_compare passing in just the salts. + * It is an extra layer of indirection, but keeps the function from + * having to know about our structure, or the db_salt structure. There + * is very little additional overhead, in this 2nd layer of indirection + * since qsort is pretty quick, and does not call compare any more than + * is needed to partition sort the data. + */ +static int ldr_salt_cmp(const void *x, const void *y) { + salt_cmp_t *X = (salt_cmp_t *)x; + salt_cmp_t *Y = (salt_cmp_t *)y; + int cmp = salt_compare(X->p->salt, Y->p->salt); + return cmp; +} + +/* + * If there are more than 1 salt, AND the format exports a salt_compare + * function, then we reorder the salt array, into the order the format + * wants them in. Reasons for this, are usually that the format can + * gain a lot of speed, if some of the salts are grouped together, so + * that the group is run one after the other. This was first done for + * the WPAPSK format, so that the format could group all ESSID's in + * the salts, so that the PBKDF2 is computed once (for the first + * instance of the ESSID), then all of the other salts which are + * different salts, but * which have the exact same ESSID will not + * have to perform the very costly PBKDF2. The format is designed + * to work that way, IFF the salts come to it in the right order. + * This function gets them into that order + */ +static void ldr_sort_salts(struct db_main *db) +{ + int i; + struct db_salt *s; +#ifndef DEBUG_SALT_SORT + salt_cmp_t *ar; +#else + salt_cmp_t ar[100]; /* array is easier to debug in VC */ +#endif + /* + * NOTE, later we will use a new format method (salt_compare) to + * determine when to do this sorting. For now, we will compute + * when (based on format name), and we have the salt_compare() + * in this file, so that we can utilize this functionality prior + * to getting this method out to every format. + */ + if (db->salt_count < 2 || + strncmp(db->format->params.label, "wpapsk", 6)) + return; + + salt_sort_db = db; +#ifndef DEBUG_SALT_SORT + ar = (salt_cmp_t *)mem_alloc(sizeof(salt_cmp_t)*db->salt_count); +#endif + s = db->salts; + + /* load our array of pointers. */ + for (i = 0; i < db->salt_count; ++i) { + ar[i].p = s; +#ifdef DEBUG_SALT_SORT + ar[i].org_idx = i; + strncpy(ar[i].str, (char*)s->salt, 36); + ar[i].str[35] = 0; /*just in case*/ +#endif + s = s->next; + } + + /* now we sort this array of pointers. */ + qsort(ar, db->salt_count, sizeof(ar[0]), ldr_salt_cmp); + + /* finally, we re-build the linked list of salts */ + db->salts = ar[0].p; + s = db->salts; + for (i = 1; i < db->salt_count; ++i) { + s->next = ar[i].p; + s = s->next; + } + s->next = 0; + +#ifndef DEBUG_SALT_SORT + MEM_FREE(ar); +#else + /* setting s here, allows me to debug quick-watch s=s->next + * over and over again while watching the char* value of s->salt + */ + s = db->salts; +#endif +} + /* * Remove the previously-cracked hashes marked with "binary = NULL" by * ldr_load_pot_line(). @@ -867,6 +999,7 @@ void ldr_fix_database(struct db_main *db ldr_filter_salts(db); ldr_remove_marked(db); + ldr_sort_salts(db); ldr_init_hash(db); diff -urpN 179-b/src/wpapsk.h 179-a/src/wpapsk.h --- 179-b/src/wpapsk.h 2013-01-30 16:47:12.308000000 -0600 +++ 179-a/src/wpapsk.h 2013-01-24 17:30:58.000000000 -0600 @@ -234,6 +234,51 @@ static void insert_nonce(uint8_t * data) } } +char *tomac(unsigned char *p) { + static char buf[48]; + sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", p[0], p[1], p[2], p[3], p[4], p[5]); + return buf; +} +char *hex(unsigned char *p, int len) { + static char buf[1024]; + char *op=buf; + int i; + if (len > 32) { + do { + for (i = 0; i < 32; ++i) { + op += sprintf (op, "%02X", p[i]); + if (i<31&&i%4==3) + op += sprintf (op, " "); + if (i==15) + op += sprintf (op, ": "); + } + len -= 32; + p += 32; + op += sprintf (op, "\n "); + } while (len > 32); + } + for (i = 0; i < len; ++i) { + op += sprintf (op, "%02X", p[i]); + if (i<31&&i%4==3) + op += sprintf (op, " "); + if (i==15) + op += sprintf (op, ": "); + } + return buf; +} + +static void Debug_hccap() { + printf("essid: %s\n", hccap.essid); + printf("mac1: %s\n", tomac(hccap.mac1)); + printf("mac2: %s\n", tomac(hccap.mac2)); + printf("nonce1: %s\n", hex(hccap.nonce1, 32)); + printf("nonce2: %s\n", hex(hccap.nonce2, 32)); + printf("eapol: %s\n", hex(hccap.eapol, 256)); + printf("epol_sz: %d (0x%02X)\n", hccap.eapol_size, hccap.eapol_size); + printf("keyver: %d\n", hccap.keyver); + printf("keymic: %s\n", hex(hccap.keymic, 16)); +} + static void set_salt(void *salt) { memcpy(&hccap, salt, SALT_SIZE); @@ -254,6 +299,7 @@ static void set_salt(void *salt) HANDLE_CLERROR(clEnqueueWriteBuffer(queue[ocl_gpu_id], mem_salt, CL_FALSE, 0, sizeof(wpapsk_salt), ¤tsalt, 0, NULL, NULL), "Copy setting to gpu"); #endif + //Debug_hccap(); } #undef set_key