#include #include #include #include #include #include #include typedef union uwb { unsigned w; unsigned char b[4]; } WBunion; typedef unsigned Digest[4]; unsigned f0(unsigned abcd[]) { return (abcd[1] &abcd[2]) | (~abcd[1] &abcd[3]); } unsigned f1(unsigned abcd[]) { return (abcd[3] &abcd[1]) | (~abcd[3] &abcd[2]); } unsigned f2(unsigned abcd[]) { return abcd[1] ^ abcd[2] ^ abcd[3]; } unsigned f3(unsigned abcd[]) { return abcd[2] ^ (abcd[1] | ~abcd[3]); } typedef unsigned(*DgstFctn)(unsigned a[]); unsigned* calcKs(unsigned *k) { double s, pwr; int i; pwr = pow(2, 32); for (i = 0; i < 64; i++) { s = fabs(sin(1 + i)); k[i] = (unsigned)(s *pwr); } return k; } // ROtate v Left by amt bits unsigned rol(unsigned v, short amt) { unsigned msk1 = (1 << amt) - 1; return ((v >> (32 - amt)) &msk1) | ((v << amt) &~msk1); } unsigned* md5(const char *msg, int mlen) { static Digest h0 = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476 }; //static Digest h0 = { 0x01234567, 0x89ABCDEF, 0xFEDCBA98, 0x76543210 }; static DgstFctn ff[] = { &f0, &f1, &f2, &f3 }; static short M[] = { 1, 5, 3, 7 }; static short O[] = { 0, 1, 5, 0 }; static short rot0[] = { 7, 12, 17, 22 }; static short rot1[] = { 5, 9, 14, 20 }; static short rot2[] = { 4, 11, 16, 23 }; static short rot3[] = { 6, 10, 15, 21 }; static short *rots[] = { rot0, rot1, rot2, rot3 }; static unsigned kspace[64]; static unsigned * k; static Digest h; Digest abcd; DgstFctn fctn; short m, o, g; unsigned f; short * rotn; union { unsigned w[16]; char b[64]; } mm; int os = 0; int grp, grps, q, p; unsigned char *msg2; if (k == NULL) k = calcKs(kspace); for (q = 0; q < 4; q++) h[q] = h0[q]; { grps = 1 + (mlen + 8) / 64; msg2 = malloc(64 *grps); memcpy(msg2, msg, mlen); msg2[mlen] = (unsigned char) 0x80; q = mlen + 1; while (q < 64 *grps) { msg2[q] = 0; q++; } { WBunion u; u.w = 8 * mlen; q -= 8; memcpy(msg2 + q, &u.w, 4); } } for (grp = 0; grp < grps; grp++) { memcpy(mm.b, msg2 + os, 64); for (q = 0; q < 4; q++) abcd[q] = h[q]; for (p = 0; p < 4; p++) { fctn = ff[p]; rotn = rots[p]; m = M[p]; o = O[p]; for (q = 0; q < 16; q++) { g = (m *q + o) % 16; f = abcd[1] + rol(abcd[0] + fctn(abcd) + k[q + 16 *p] + mm.w[g], rotn[q % 4]); abcd[0] = abcd[3]; abcd[3] = abcd[2]; abcd[2] = abcd[1]; abcd[1] = f; } } for (p = 0; p < 4; p++) h[p] += abcd[p]; os += 64; } if (msg2) free(msg2); return h; } char *get_mac() { FILE * fp; char *mac = malloc(18* sizeof(char)); fp = fopen("/sys/class/net/ap0/address", "r"); fgets(mac, 17, fp); fclose(fp); return mac; } char *get_serial() { FILE * fp; char *serial = malloc(21* sizeof(char)); fp = fopen("/etc/serial", "r"); fgets(serial, 20, fp); return serial; } int gen_serial() { // hexdump -n 16 -e '4/4 "%08X" 1 "\n"' /dev/random if (fopen("/etc/serial", "r") == NULL) { system("/usr/bin/hexdump -n 16 -e '4/4 \"%08X\"' /dev/urandom > /etc/serial"); } } int gen_update_key() { if (fopen("/etc/update_key", "r") == NULL) { system("/usr/bin/hexdump -n 32 -e '4/4 \"%08X\"' /dev/urandom > /etc/update_key"); } chmod("/etc/update_key", 0600); } int gen_ssid() { char *serial; FILE * fp; char ssid[20] = "CyberChallenge-"; serial = get_serial(); strncat(ssid, serial, 4); fp = fopen("/etc/ssid", "w"); fprintf(fp, "%s", ssid); fclose(fp); } int gen_key(char *serial, char *mac) { FILE * fp; char md5a[33]; char md5b[33]; char tmp[3]; char key[21]; char wstr[9]; char xstr[9]; char ystr[9]; char zstr[9]; uint32_t w, x, y, z; long long int seed; int j, k; unsigned long int h; WBunion u; md5a[0] = '\0'; md5b[0] = '\0'; wstr[8] = '\0'; xstr[8] = '\0'; ystr[8] = '\0'; zstr[8] = '\0'; unsigned *d = md5(mac, strlen(mac)); for (j = 0; j < 4; j++) { u.w = d[j]; for (k = 0; k < 4; k++) { snprintf(tmp, 3, "%02x", u.b[k]); strncat(md5a, tmp, 2); } } unsigned *f = md5(serial, strlen(serial)); for (j = 0; j < 4; j++) { u.w = f[j]; for (k = 0; k < 4; k++) { snprintf(tmp, 3, "%02x", u.b[k]); strncat(md5b, tmp, 2); } } strncpy(wstr, md5a, 8); strncpy(xstr, md5a + 8, 8); strncpy(ystr, md5a + 16, 8); strncpy(zstr, md5a + 24, 8); w = strtoul(wstr, NULL, 16); x = strtoul(xstr, NULL, 16); y = strtoul(ystr, NULL, 16); z = strtoul(zstr, NULL, 16); for (int i = 0; i < 20; ++i) { uint32_t t = x; t ^= t << 11U; t ^= t >> 8U; x = y; y = z; z = w; w ^= w >> 19U; w ^= t; key[i] = md5b[t % 20]; } key[20] = '\0'; fp = fopen("/etc/wpa", "w"); fprintf(fp, "%s", key); fclose(fp); } int main() { char *mac; char *serial; gen_serial(); gen_ssid(); mac = get_mac(); serial = get_serial(); gen_key(mac, serial); return 0; }