aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCody Kesting <ckesting@google.com>2019-10-30 13:25:56 -0700
committerandroid-build-merger <android-build-merger@google.com>2019-10-30 13:25:56 -0700
commit3074ff706946cee394815e0b838f63429e4bb93c (patch)
tree4ddaacad101486740a7cedd73326dd030ac1f736
parent7ec43bb63988dbd8518a5769457e808c3710ebfa (diff)
parenteedd8d2f6549ec2dee1dfcfbf0a7f96243db4c18 (diff)
downloadike-3074ff706946cee394815e0b838f63429e4bb93c.tar.gz
Create CK' and IK' for EAP-AKA'. am: 3868e2aa52
am: eedd8d2f65 Change-Id: I482653a455fdce1de5705c57cef697e023ba8e98
-rw-r--r--src/java/com/android/ike/eap/statemachine/EapAkaPrimeMethodStateMachine.java46
-rw-r--r--tests/iketests/src/java/com/android/ike/eap/statemachine/EapAkaPrimeChallengeStateTest.java27
2 files changed, 73 insertions, 0 deletions
diff --git a/src/java/com/android/ike/eap/statemachine/EapAkaPrimeMethodStateMachine.java b/src/java/com/android/ike/eap/statemachine/EapAkaPrimeMethodStateMachine.java
index 1b365dc7..f047cf6f 100644
--- a/src/java/com/android/ike/eap/statemachine/EapAkaPrimeMethodStateMachine.java
+++ b/src/java/com/android/ike/eap/statemachine/EapAkaPrimeMethodStateMachine.java
@@ -32,17 +32,23 @@ import com.android.ike.eap.message.simaka.EapAkaPrimeTypeData;
import com.android.ike.eap.message.simaka.EapAkaPrimeTypeData.EapAkaPrimeTypeDataDecoder;
import com.android.ike.eap.message.simaka.EapAkaTypeData;
import com.android.ike.eap.message.simaka.EapSimAkaAttribute;
+import com.android.ike.eap.message.simaka.EapSimAkaAttribute.AtAutn;
import com.android.ike.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode;
import com.android.ike.eap.message.simaka.EapSimAkaAttribute.AtKdf;
import com.android.ike.eap.message.simaka.EapSimAkaAttribute.AtKdfInput;
import com.android.ike.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
import com.android.internal.annotations.VisibleForTesting;
+import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
/**
* EapAkaPrimeMethodStateMachine represents the valid paths possible for the EAP-AKA' protocol.
*
@@ -68,6 +74,9 @@ public class EapAkaPrimeMethodStateMachine extends EapAkaMethodStateMachine {
// EAP-AKA' identity prefix (RFC 5448#3)
private static final String AKA_PRIME_IDENTITY_PREFIX = "6";
private static final int SUPPORTED_KDF = 1;
+ private static final int FC = 0x20; // Required by TS 133 402 Annex A.2
+ private static final int SQN_XOR_AK_LEN = 6;
+ private static final String MAC_ALGORITHM_STRING = "HmacSHA256";
private final EapAkaPrimeConfig mEapAkaPrimeConfig;
private final EapAkaPrimeTypeDataDecoder mEapAkaPrimeTypeDataDecoder;
@@ -203,6 +212,43 @@ public class EapAkaPrimeMethodStateMachine extends EapAkaMethodStateMachine {
return true;
}
+
+ /**
+ * Derives CK' and IK' values from CK and IK
+ *
+ * <p>CK' and IK' generation is specified in TS 133 402 Annex A.2, which relies on the key
+ * derivation function KDF specified in TS 133 220 Annex B.2.
+ */
+ @VisibleForTesting
+ byte[] deriveCkIkPrime(
+ RandChallengeResult randChallengeResult, AtKdfInput atKdfInput, AtAutn atAutn)
+ throws GeneralSecurityException {
+ final int fcLen = 1;
+ int lengthFieldLen = 2;
+
+ // SQN ^ AK is the first 6B of the AUTN value
+ byte[] sqnXorAk = Arrays.copyOf(atAutn.autn, SQN_XOR_AK_LEN);
+ int sLength =
+ fcLen
+ + atKdfInput.networkName.length + lengthFieldLen
+ + SQN_XOR_AK_LEN + lengthFieldLen;
+
+ ByteBuffer dataToSign = ByteBuffer.allocate(sLength);
+ dataToSign.put((byte) FC);
+ dataToSign.put(atKdfInput.networkName);
+ dataToSign.putShort((short) atKdfInput.networkName.length);
+ dataToSign.put(sqnXorAk);
+ dataToSign.putShort((short) SQN_XOR_AK_LEN);
+
+ int keyLen = randChallengeResult.ck.length + randChallengeResult.ik.length;
+ ByteBuffer key = ByteBuffer.allocate(keyLen);
+ key.put(randChallengeResult.ck);
+ key.put(randChallengeResult.ik);
+
+ Mac mac = Mac.getInstance(MAC_ALGORITHM_STRING);
+ mac.init(new SecretKeySpec(key.array(), MAC_ALGORITHM_STRING));
+ return mac.doFinal(dataToSign.array());
+ }
}
EapAkaPrimeTypeData getEapSimAkaTypeData(AtClientErrorCode clientErrorCode) {
diff --git a/tests/iketests/src/java/com/android/ike/eap/statemachine/EapAkaPrimeChallengeStateTest.java b/tests/iketests/src/java/com/android/ike/eap/statemachine/EapAkaPrimeChallengeStateTest.java
index 43fbf41c..32041435 100644
--- a/tests/iketests/src/java/com/android/ike/eap/statemachine/EapAkaPrimeChallengeStateTest.java
+++ b/tests/iketests/src/java/com/android/ike/eap/statemachine/EapAkaPrimeChallengeStateTest.java
@@ -18,18 +18,22 @@ package com.android.ike.eap.statemachine;
import static android.telephony.TelephonyManager.APPTYPE_USIM;
+import static com.android.ike.TestUtils.hexStringToByteArray;
import static com.android.ike.eap.message.EapData.EAP_TYPE_AKA_PRIME;
import static com.android.ike.eap.message.EapMessage.EAP_CODE_REQUEST;
+import static com.android.ike.eap.message.EapTestMessageDefinitions.CK_BYTES;
import static com.android.ike.eap.message.EapTestMessageDefinitions.EAP_AKA_PRIME_AUTHENTICATION_REJECT;
import static com.android.ike.eap.message.EapTestMessageDefinitions.EAP_AKA_PRIME_IDENTITY_BYTES;
import static com.android.ike.eap.message.EapTestMessageDefinitions.EAP_AKA_PRIME_IDENTITY_RESPONSE;
import static com.android.ike.eap.message.EapTestMessageDefinitions.ID_INT;
+import static com.android.ike.eap.message.EapTestMessageDefinitions.IK_BYTES;
import static com.android.ike.eap.message.EapTestMessageDefinitions.IMSI;
import static com.android.ike.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE;
import static com.android.ike.eap.message.simaka.EapAkaTypeData.EAP_AKA_IDENTITY;
import static com.android.ike.eap.message.simaka.attributes.EapTestAttributeDefinitions.AUTN_BYTES;
import static com.android.ike.eap.message.simaka.attributes.EapTestAttributeDefinitions.MAC_BYTES;
import static com.android.ike.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1_BYTES;
+import static com.android.ike.eap.message.simaka.attributes.EapTestAttributeDefinitions.RES_BYTES;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertFalse;
@@ -52,6 +56,7 @@ import com.android.ike.eap.message.simaka.EapSimAkaAttribute.AtKdfInput;
import com.android.ike.eap.message.simaka.EapSimAkaAttribute.AtMac;
import com.android.ike.eap.message.simaka.EapSimAkaAttribute.AtRandAka;
import com.android.ike.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
+import com.android.ike.eap.statemachine.EapAkaMethodStateMachine.ChallengeState.RandChallengeResult;
import com.android.ike.eap.statemachine.EapAkaPrimeMethodStateMachine.ChallengeState;
import org.junit.Before;
@@ -71,6 +76,10 @@ public class EapAkaPrimeChallengeStateTest extends EapAkaPrimeStateTest {
private static final int VALID_KDF = 1;
private static final int INVALID_KDF = 10;
+ private static final byte[] EXPECTED_CK_IK_PRIME =
+ hexStringToByteArray(
+ "A0B37E7C7E9CC4F37A5C0AAA55DC87BE51FDA70A9D8F37E62E23B15F1B3941E6");
+
private ChallengeState mState;
@Before
@@ -269,4 +278,22 @@ public class EapAkaPrimeChallengeStateTest extends EapAkaPrimeStateTest {
assertFalse(
mState.hasMatchingNetworkNames(INCORRECT_NETWORK_NAME, SERVER_NETWORK_NAME_STRING));
}
+
+ @Test
+ public void testDeriveCkIkPrime() throws Exception {
+ RandChallengeResult randChallengeResult =
+ mState.new RandChallengeResult(RES_BYTES, IK_BYTES, CK_BYTES);
+ AtKdfInput atKdfInput =
+ new AtKdfInput(0, PEER_NETWORK_NAME.getBytes(StandardCharsets.UTF_8));
+ AtAutn atAutn = new AtAutn(AUTN_BYTES);
+
+ // S = FC | Network Name | len(Network Name) | SQN ^ AK | len(SQN ^ AK)
+ // = 20666F6F3A62617200070123456789AB0006
+ // K = CK | IK
+ // = FFEEDDCCBBAA9988776655443322110000112233445566778899AABBCCDDEEFF
+ // CK' | IK' = HMAC-SHA256(K, S)
+ // = A0B37E7C7E9CC4F37A5C0AAA55DC87BE51FDA70A9D8F37E62E23B15F1B3941E6
+ byte[] result = mState.deriveCkIkPrime(randChallengeResult, atKdfInput, atAutn);
+ assertArrayEquals(EXPECTED_CK_IK_PRIME, result);
+ }
}