/****************************************************************/ /* 802.11 Password Hashing Test Vector Generator */ /* (c) 2002, David Johnston */ /* Author: David Johnston */ /* Email (home): dj@deadhat.com */ /* Email (general) : david.johnston@ieee.org */ /* Version 0.1 */ /****************************************************************/ #include #include #define MAX_MESSAGE_LENGTH 4096 /****************************************/ /* Text output options. */ /* Comment out to reduce text output */ /****************************************/ void debug_out( unsigned char *label, unsigned char *data, int data_length ); /********************************************/ /* Test Cases */ /* An array of test cases, each containing */ /* a block to be processed by michael */ /********************************************/ #define NUM_TEST_CASES 3 int passphrase_lengths[] = {8, 15, 32}; int ssid_lengths[] = {4, 11, 32}; unsigned char passphrases[] = { 'p','a','s','s','w','o','r','d', 'T','h','i','s','I','s','A','P','a','s','s','w','o','r','d', 'a','a','a','a','a','a','a','a', 'a','a','a','a','a','a','a','a', 'a','a','a','a','a','a','a','a', 'a','a','a','a','a','a','a','a' }; unsigned char ssids[] = { 'I','E','E','E', 'T','h','i','s','I','s','A','S','S','I','D', 'Z','Z','Z','Z','Z','Z','Z','Z', 'Z','Z','Z','Z','Z','Z','Z','Z', 'Z','Z','Z','Z','Z','Z','Z','Z', 'Z','Z','Z','Z','Z','Z','Z','Z' }; /****************************************/ /* sha1() */ /* Performs the NIST SHA-1 algorithm */ /****************************************/ unsigned long int ft( int t, unsigned long int x, unsigned long int y, unsigned long int z ) { unsigned long int a,b,c; if (t < 20) { a = x & y; b = (~x) & z; c = a ^ b; } else if (t < 40) { c = x ^ y ^ z; } else if (t < 60) { a = x & y; b = a ^ (x & z); c = b ^ (y & z); } else if (t < 80) { c = (x ^ y) ^ z; } return c; } unsigned long int k(int t) { unsigned long int c; if (t < 20) { c = 0x5a827999; } else if (t < 40) { c = 0x6ed9eba1; } else if (t < 60) { c = 0x8f1bbcdc; } else if (t < 80) { c = 0xca62c1d6; } return c; } unsigned long int rotr(int bits, unsigned long int a) { unsigned long int c,d,e,f,g; c = (0x0001 << bits)-1; d = ~c; e = (a & d) >> bits; f = (a & c) << (32 - bits); g = e | f; return (g & 0xffffffff ); } unsigned long int rotl(int bits, unsigned long int a) { unsigned long int c,d,e,f,g; c = (0x0001 << (32-bits))-1; d = ~c; e = (a & c) << bits; f = (a & d) >> (32 - bits); g = e | f; return (g & 0xffffffff ); } void sha1 ( unsigned char *message, int message_length, unsigned char *digest ) { int i; int num_blocks; int block_remainder; int padded_length; unsigned long int l; unsigned long int t; unsigned long int h[5]; unsigned long int a,b,c,d,e; unsigned long int w[80]; unsigned long int temp; #ifdef SHA1_DEBUG int x,y; #endif /* Calculate the number of 512 bit blocks */ padded_length = message_length + 8; /* Add length for l */ padded_length = padded_length + 1; /* Add the 0x01 bit postfix */ l = message_length * 8; num_blocks = padded_length / 64; block_remainder = padded_length % 64; if (block_remainder > 0) { num_blocks++; } padded_length = padded_length + (64 - block_remainder); /* clear the padding field */ for (i = message_length; i < (num_blocks * 64); i++) { message[i] = 0x00; } /* insert b1 padding bit */ message[message_length] = 0x80; /* Insert l */ message[(num_blocks*64)-1] = (unsigned char)( l & 0xff); message[(num_blocks*64)-2] = (unsigned char)((l >> 8) & 0xff); message[(num_blocks*64)-3] = (unsigned char)((l >> 16) & 0xff); message[(num_blocks*64)-4] = (unsigned char)((l >> 24) & 0xff); /* Set initial hash state */ h[0] = 0x67452301; h[1] = 0xefcdab89; h[2] = 0x98badcfe; h[3] = 0x10325476; h[4] = 0xc3d2e1f0; #ifdef SHA1_DEBUG printf("INITIAL message_length = %d\n", message_length); printf("INITIAL padded_length = %d\n", padded_length); printf("INITIAL num_blocks = %d\n", num_blocks); for (x=0;x> 8) & 0xff); digest[1] = (unsigned char) ((h[0] >> 16) & 0xff); digest[0] = (unsigned char) ((h[0] >> 24) & 0xff); digest[7] = (unsigned char) ( h[1] & 0xff); digest[6] = (unsigned char) ((h[1] >> 8) & 0xff); digest[5] = (unsigned char) ((h[1] >> 16) & 0xff); digest[4] = (unsigned char) ((h[1] >> 24) & 0xff); digest[11] = (unsigned char) ( h[2] & 0xff); digest[10] = (unsigned char) ((h[2] >> 8) & 0xff); digest[9] = (unsigned char) ((h[2] >> 16) & 0xff); digest[8] = (unsigned char) ((h[2] >> 24) & 0xff); digest[15] = (unsigned char) ( h[3] & 0xff); digest[14] = (unsigned char) ((h[3] >> 8) & 0xff); digest[13] = (unsigned char) ((h[3] >> 16) & 0xff); digest[12] = (unsigned char) ((h[3] >> 24) & 0xff); digest[19] = (unsigned char) ( h[4] & 0xff); digest[18] = (unsigned char) ((h[4] >> 8) & 0xff); digest[17] = (unsigned char) ((h[4] >> 16) & 0xff); digest[16] = (unsigned char) ((h[4] >> 24) & 0xff); } /******************************************************/ /* hmac-sha1() */ /* Performs the hmac-sha1 keyed secure hash algorithm */ /******************************************************/ void hmac_sha1( unsigned char *key, int key_length, unsigned char *data, int data_length, unsigned char *digest ) { int b = 64; /* blocksize */ unsigned char ipad = 0x36; unsigned char opad = 0x5c; unsigned char k0[64]; unsigned char k0xorIpad[64]; unsigned char step7data[64]; unsigned char step5data[MAX_MESSAGE_LENGTH+128]; unsigned char step8data[64+20]; int i; for (i=0; i<64; i++) { k0[i] = 0x00; } if (key_length != b) /* Step 1 */ { /* Step 2 */ if (key_length > b) { sha1(key, key_length, digest); for (i=0;i<20;i++) { k0[i]=digest[i]; } } else if (key_length < b) /* Step 3 */ { for (i=0; i 0) { printf("\t"); for (j=0; j