static void aes_gcm_ghash(const u8 *H, const u8 *aad, size_t aad_len, const u8 *crypt, size_t crypt_len, u8 *S) { u8 len_buf[16]; /* * u = 128 * ceil[len(C)/128] - len(C) * v = 128 * ceil[len(A)/128] - len(A) * S = GHASH_H(A || 0^v || C || 0^u || [len(A)]64 || [len(C)]64) * (i.e., zero padded to block size A || C and lengths of each in bits) */ ghash_start(S); ghash(H, aad, aad_len, S); ghash(H, crypt, crypt_len, S); // AIDEN - Used to be: WPA_PUT_BE64(len_buf, aad_len * 8); WPA_PUT_BE32(len_buf, 0); WPA_PUT_BE32(len_buf + 4, aad_len * 8); // AIDEN - Used to be: WPA_PUT_BE64(len_buf + 8, crypt_len * 8); WPA_PUT_BE32(len_buf + 8, 0); WPA_PUT_BE32(len_buf + 12, crypt_len * 8); ghash(H, len_buf, sizeof(len_buf), S); /* wpa_hexdump_key(MSG_EXCESSIVE, "S = GHASH_H(...)", S, 16); */ }
static void aes_gcm_prepare_j0(const u8 *iv, size_t iv_len, const u8 *H, u8 *J0) { u8 len_buf[16]; #ifndef OT_AESGCM_AES128_IV12_ONLY // DHD20150614 if (iv_len == 12) { #endif // DHD20150614 /* Prepare block J_0 = IV || 0^31 || 1 [len(IV) = 96] */ os_memcpy(J0, iv, iv_len); os_memset(J0 + iv_len, 0, AES_BLOCK_SIZE - iv_len); J0[AES_BLOCK_SIZE - 1] = 0x01; #ifndef OT_AESGCM_AES128_IV12_ONLY // DHD20150614 } else { /* * s = 128 * ceil(len(IV)/128) - len(IV) * J_0 = GHASH_H(IV || 0^(s+64) || [len(IV)]_64) */ ghash_start(J0); ghash(H, iv, iv_len, J0); // AIDEN - Used to be: WPA_PUT_BE64(len_buf, 0); WPA_PUT_BE32(len_buf, 0); WPA_PUT_BE32(len_buf + 4, 0); // AIDEN - Used to be: WPA_PUT_BE64(len_buf + 8, iv_len * 8); WPA_PUT_BE32(len_buf + 8, 0); WPA_PUT_BE32(len_buf + 12, iv_len * 8); ghash(H, len_buf, sizeof(len_buf), J0); } #endif // DHD20150614 }
static void aes_gcm_ghash(const aes_uchar *H, const aes_uchar *aad, size_t aad_len, const aes_uchar *crypt, size_t crypt_len, aes_uchar *S) { aes_uchar len_buf[16]; /* * u = 128 * ceil[len(C)/128] - len(C) * v = 128 * ceil[len(A)/128] - len(A) * S = GHASH_H(A || 0^v || C || 0^u || [len(A)]64 || [len(C)]64) * (i.e., zero padded to block size A || C and lengths of each in bits) */ ghash_start(S); ghash(H, aad, aad_len, S); ghash(H, crypt, crypt_len, S); AES_PUT_BE64(len_buf, aad_len * 8); AES_PUT_BE64(len_buf + 8, crypt_len * 8); ghash(H, len_buf, sizeof(len_buf), S); aes_hexdump_key(MSG_EXCESSIVE, "S = GHASH_H(...)", S, 16); }
static void aes_gcm_prepare_j0(const aes_uchar *iv, size_t iv_len, const aes_uchar *H, aes_uchar *J0) { aes_uchar len_buf[16]; if (iv_len == 12) { /* Prepare block J_0 = IV || 0^31 || 1 [len(IV) = 96] */ memcpy(J0, iv, iv_len); memset(J0 + iv_len, 0, AES_BLOCK_SIZE - iv_len); J0[AES_BLOCK_SIZE - 1] = 0x01; } else { /* * s = 128 * ceil(len(IV)/128) - len(IV) * J_0 = GHASH_H(IV || 0^(s+64) || [len(IV)]_64) */ ghash_start(J0); ghash(H, iv, iv_len, J0); AES_PUT_BE64(len_buf, 0); AES_PUT_BE64(len_buf + 8, iv_len * 8); ghash(H, len_buf, sizeof(len_buf), J0); } }
static PyObject * ghash_function(PyObject *self, PyObject *args) { PyObject *data, *y, *exp_h; PyObject *retval = NULL; Py_ssize_t len_data, len_y, len_exp_h; if (!PyArg_ParseTuple(args, "SSS", &data, &y, &exp_h)) { goto out; } len_data = PyBytes_GET_SIZE(data); len_y = PyBytes_GET_SIZE(y); len_exp_h = PyBytes_GET_SIZE(exp_h); if (len_data%16!=0) { PyErr_SetString(PyExc_ValueError, "Length of data must be a multiple of 16 bytes."); goto out; } if (len_y!=16) { PyErr_SetString(PyExc_ValueError, "Length of y must be 16 bytes."); goto out; } if (len_exp_h!=sizeof(t_key_tables) && len_exp_h!=16) { PyErr_SetString(PyExc_ValueError, "Length of expanded key is incorrect."); goto out; } /* Create return string */ retval = PyBytes_FromStringAndSize(NULL, 16); if (!retval) { goto out; } Py_BEGIN_ALLOW_THREADS; #define PyBytes_Buffer(a) (uint8_t*)PyBytes_AS_STRING(a) ghash( PyBytes_Buffer(retval), PyBytes_Buffer(data), len_data, PyBytes_Buffer(y), PyBytes_Buffer(exp_h), len_exp_h ); #undef PyBytes_Buffer Py_END_ALLOW_THREADS; out: return retval; }