static int test_gcm(void) { int ret = 0; int i; u8 k[32], aad[32], iv[64], t[16], tag[16]; u8 p[64], c[64], tmp[64]; size_t k_len, p_len, aad_len, iv_len; for (i = 0; i < ARRAY_SIZE(gcm_tests); i++) { const struct gcm_test_vector *tc = &gcm_tests[i]; k_len = os_strlen(tc->k) / 2; if (hexstr2bin(tc->k, k, k_len)) { printf("Invalid GCM test vector %d (k)\n", i); ret++; continue; } p_len = os_strlen(tc->p) / 2; if (hexstr2bin(tc->p, p, p_len)) { printf("Invalid GCM test vector %d (p)\n", i); ret++; continue; } aad_len = os_strlen(tc->aad) / 2; if (hexstr2bin(tc->aad, aad, aad_len)) { printf("Invalid GCM test vector %d (aad)\n", i); ret++; continue; } iv_len = os_strlen(tc->iv) / 2; if (hexstr2bin(tc->iv, iv, iv_len)) { printf("Invalid GCM test vector %d (iv)\n", i); ret++; continue; } if (hexstr2bin(tc->c, c, p_len)) { printf("Invalid GCM test vector %d (c)\n", i); ret++; continue; } if (hexstr2bin(tc->t, t, sizeof(t))) { printf("Invalid GCM test vector %d (t)\n", i); ret++; continue; } if (aes_gcm_ae(k, k_len, iv, iv_len, p, p_len, aad, aad_len, tmp, tag) < 0) { printf("GCM-AE failed (test case %d)\n", i); ret++; continue; } if (os_memcmp(c, tmp, p_len) != 0) { printf("GCM-AE mismatch (test case %d)\n", i); ret++; } if (os_memcmp(tag, t, sizeof(tag)) != 0) { printf("GCM-AE tag mismatch (test case %d)\n", i); ret++; } if (p_len == 0) { if (aes_gmac(k, k_len, iv, iv_len, aad, aad_len, tag) < 0) { printf("GMAC failed (test case %d)\n", i); ret++; continue; } if (os_memcmp(tag, t, sizeof(tag)) != 0) { printf("GMAC tag mismatch (test case %d)\n", i); ret++; } } if (aes_gcm_ad(k, k_len, iv, iv_len, c, p_len, aad, aad_len, t, tmp) < 0) { printf("GCM-AD failed (test case %d)\n", i); ret++; continue; } if (os_memcmp(p, tmp, p_len) != 0) { printf("GCM-AD mismatch (test case %d)\n", i); ret++; } } return ret; }
u8 * bip_gmac_protect(const u8 *igtk, size_t igtk_len, u8 *frame, size_t len, u8 *ipn, int keyid, size_t *prot_len) { u8 *prot, *pos, *buf; u16 fc; struct ieee80211_hdr *hdr; size_t plen; u8 nonce[12], *npos; plen = len + 26; prot = os_malloc(plen); if (prot == NULL) return NULL; os_memcpy(prot, frame, len); pos = prot + len; *pos++ = WLAN_EID_MMIE; *pos++ = 24; WPA_PUT_LE16(pos, keyid); pos += 2; os_memcpy(pos, ipn, 6); pos += 6; os_memset(pos, 0, 16); /* MIC */ buf = os_malloc(plen + 20 - 24); if (buf == NULL) { os_free(prot); return NULL; } /* BIP AAD: FC(masked) A1 A2 A3 */ hdr = (struct ieee80211_hdr *) frame; fc = le_to_host16(hdr->frame_control); fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA); WPA_PUT_LE16(buf, fc); os_memcpy(buf + 2, hdr->addr1, 3 * ETH_ALEN); os_memcpy(buf + 20, prot + 24, plen - 24); wpa_hexdump(MSG_MSGDUMP, "BIP-GMAC: AAD|Body(masked)", buf, plen + 20 - 24); /* Nonce: A2 | IPN */ os_memcpy(nonce, hdr->addr2, ETH_ALEN); npos = nonce + ETH_ALEN; *npos++ = ipn[5]; *npos++ = ipn[4]; *npos++ = ipn[3]; *npos++ = ipn[2]; *npos++ = ipn[1]; *npos++ = ipn[0]; wpa_hexdump(MSG_EXCESSIVE, "BIP-GMAC: Nonce", nonce, sizeof(nonce)); /* MIC = AES-GMAC(AAD || Frame Body(masked)) */ if (aes_gmac(igtk, igtk_len, nonce, sizeof(nonce), buf, plen + 20 - 24, pos) < 0) { os_free(prot); os_free(buf); return NULL; } os_free(buf); wpa_hexdump(MSG_DEBUG, "BIP-GMAC MMIE MIC", pos, 16); *prot_len = plen; return prot; }
static int test_gcm(void) { int ret = 0; int i; u8 k[32], aad[32], iv[64], t[16], tag[16]; u8 p[64], c[64], tmp[64]; size_t k_len, p_len, aad_len, iv_len; printf ("testing gcm\n"); for (i = 0; i < ARRAY_SIZE(gcm_tests); i++) { const struct gcm_test_vector *tc = &gcm_tests[i]; k_len = strlen(tc->k) / 2; if (hexstr2bin(tc->k, k, k_len)) { printf("Invalid GCM test vector %d (k)\n", i); ret++; continue; } p_len = strlen(tc->p) / 2; if (hexstr2bin(tc->p, p, p_len)) { printf("Invalid GCM test vector %d (p)\n", i); ret++; continue; } aad_len = strlen(tc->aad) / 2; if (hexstr2bin(tc->aad, aad, aad_len)) { printf("Invalid GCM test vector %d (aad)\n", i); ret++; continue; } iv_len = strlen(tc->iv) / 2; if (hexstr2bin(tc->iv, iv, iv_len)) { printf("Invalid GCM test vector %d (iv)\n", i); ret++; continue; } if (hexstr2bin(tc->c, c, p_len)) { printf("Invalid GCM test vector %d (c)\n", i); ret++; continue; } if (hexstr2bin(tc->t, t, sizeof(t))) { printf("Invalid GCM test vector %d (t)\n", i); ret++; continue; } if (k_len == 32 && iv_len == 12) { printf ("k: %s\n", tc->k); printf ("iv: %s\n", tc->iv); printf ("p: %s\n", tc->p); printf ("aad: %s\n", tc->aad); } if (aes_gcm_ae(k, k_len, iv, iv_len, p, p_len, aad, aad_len, tmp, tag) < 0) { printf("GCM-AE failed (test case %d)\n", i); ret++; continue; } else if (k_len == 32 && iv_len == 12) { for (int i=0; i< sizeof tmp; i++) printf ("%02X", tmp[i]); printf ("\n"); for (int i=0; i< sizeof tag; i++) printf ("%02X", tag[i]); printf ("\n"); printf ("k_len: %lu, iv_len: %lu, p_len: %lu, aad_len: %lu\n", k_len, iv_len, p_len, aad_len); } if (memcmp(c, tmp, p_len) != 0) { printf("GCM-AE mismatch (test case %d)\n", i); ret++; } if (memcmp(tag, t, sizeof(tag)) != 0) { printf("GCM-AE tag mismatch (test case %d)\n", i); ret++; } if (p_len == 0) { if (aes_gmac(k, k_len, iv, iv_len, aad, aad_len, tag) < 0) { printf("GMAC failed (test case %d)\n", i); ret++; continue; } if (memcmp(tag, t, sizeof(tag)) != 0) { printf("GMAC tag mismatch (test case %d)\n", i); ret++; } } if (aes_gcm_ad(k, k_len, iv, iv_len, c, p_len, aad, aad_len, t, tmp) < 0) { printf("GCM-AD failed (test case %d)\n", i); ret++; continue; } else { printf ("uyup\n"); } if (memcmp(p, tmp, p_len) != 0) { printf("GCM-AD mismatch (test case %d)\n", i); ret++; } } return ret; }