3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-12-22 21:22:37 +01:00

simutil: removed milenage algorithm from simutil

The simauth module now checks the milenage values
This commit is contained in:
James Prestwood 2017-12-13 14:29:12 -08:00 committed by Denis Kenzior
parent 1fa218fc8d
commit 3de239ed9e

View File

@ -143,133 +143,6 @@ static void G(uint32_t *out, uint8_t *block)
memcpy(out, H, sizeof(H));
}
/*
* Helper to XOR an array
* to - result of XOR array
* a - array 1
* b - array 2
* len - size of aray
*/
#define XOR(to, a, b, len) \
for (i = 0; i < len; i++) { \
to[i] = a[i] ^ b[i]; \
}
bool eap_aka_get_milenage(const uint8_t *opc, const uint8_t *k,
const uint8_t *rand, const uint8_t *sqn, const uint8_t *amf,
uint8_t *autn, uint8_t *ck, uint8_t *ik, uint8_t *res)
{
/* algorithm variables: TEMP, IN1, OUT1, OUT2, OUT5 (OUT3/4 == IK/CK) */
uint8_t temp[16];
uint8_t in1[16];
uint8_t out1[16], out2[16], out5[16];
/* other variables */
struct l_cipher *aes;
int i;
uint8_t tmp1[16];
uint8_t tmp2[16];
aes = l_cipher_new(L_CIPHER_AES, k, 16);
/* temp = TEMP = E[RAND ^ OPc]k */
XOR(tmp1, rand, opc, 16);
l_cipher_encrypt(aes, tmp1, temp, 16);
/* IN1[0-47] = SQN[0-47] */
memcpy(in1, sqn, 6);
/* IN1[48-63] = AMF[0-15] */
memcpy(in1 + 6, amf, 2);
/* IN1[64-111] = SQN[0-47] */
memcpy(in1 + 8, sqn, 6);
/* IN1[112-127] = AMF[0-15] */
memcpy(in1 + 14, amf, 2);
/*
* f1 and f1* output OUT1
*/
/*
* tmp1 = rot(IN1 ^ OPc)r1
* r1 = 64 bits = 8 bytes
*/
for (i = 0; i < 16; i++)
tmp1[(i + 8) % 16] = in1[i] ^ opc[i];
/* tmp2 = TEMP ^ tmp1 */
XOR(tmp2, temp, tmp1, 16);
/* tmp2 = E[tmp2]k */
l_cipher_encrypt(aes, tmp2, tmp1, 16);
/* out1 = OUT1 = tmp1 ^ opc */
XOR(out1, tmp1, opc, 16);
/*
* f2 outputs OUT2 (RES | AK)
*
* r2 = 0 == no rotation
*/
/* tmp1 = rot(TEMP ^ OPc)r2 */
XOR(tmp1, temp, opc, 16);
/* tmp1 ^ c2. c2 at bit 127 == 1 */
tmp1[15] ^= 1;
l_cipher_encrypt(aes, tmp1, out2, 16);
/* get RES from OUT2 */
XOR(out2, out2, opc, 16);
memcpy(res, out2 + 8, 8);
/* AUTN = (SQN ^ AK) | AMF | MAC_A */
XOR(autn, sqn, out2, 6);
memcpy(autn + 6, amf, 2);
memcpy(autn + 8, out1, 8);
/*
* f3 outputs CK (OUT3)
*
* tmp1 = rot(TEMP ^ OPc)r3
*
* r3 = 32 bits = 4 bytes
*/
for (i = 0; i < 16; i++)
tmp1[(i + 12) % 16] = temp[i] ^ opc[i];
/* tmp1 ^ c3. c3 at bit 126 == 1 */
tmp1[15] ^= 1 << 1;
l_cipher_encrypt(aes, tmp1, ck, 16);
/* ck ^ opc */
XOR(ck, ck, opc, 16);
/*
* f4 outputs IK (OUT4)
*
* tmp1 = rot(TEMP ^ OPc)r4
*
* r4 = 64 bits = 8 bytes
*/
for (i = 0; i < 16; i++)
tmp1[(i + 8) % 16] = temp[i] ^ opc[i];
/* tmp1 ^ c4. c4 at bit 125 == 1 */
tmp1[15] ^= 1 << 2;
l_cipher_encrypt(aes, tmp1, ik, 16);
/* ik ^ opc */
XOR(ik, ik, opc, 16);
/*
* f5* outputs AK' (OUT5)
*/
for (i = 0; i < 16; i++)
tmp1[(i + 4) % 16] = temp[i] ^ opc[i];
/* tmp1 ^ c5. c5 at bit 124 == 1 */
tmp1[15] ^= 1 << 3;
l_cipher_encrypt(aes, tmp1, out5, 16);
/* out5 ^ opc */
XOR(out5, out5, opc, 16);
l_cipher_free(aes);
return true;
}
bool eap_aka_derive_primes(const uint8_t *ck, const uint8_t *ik,
const uint8_t *autn, const uint8_t *network, uint16_t net_len,
uint8_t *ck_p, uint8_t *ik_p)