diff --git a/luni/src/test/java/libcore/java/security/SignatureTest.java b/luni/src/test/java/libcore/java/security/SignatureTest.java
index 4e2cf61..4afc67d 100644
--- a/luni/src/test/java/libcore/java/security/SignatureTest.java
+++ b/luni/src/test/java/libcore/java/security/SignatureTest.java
@@ -246,7 +246,7 @@
             + "34fdadc44326b9b3f3fa828652bab07f0362ac141c8c3784ebdec44e0b156a5e7bccdc81a56fe954"
             + "56ac8c0e4ae12d97");
 
-    private static byte[] hexToBytes(String s) {
+    public static byte[] hexToBytes(String s) {
         int len = s.length();
         byte[] data = new byte[len / 2];
         for (int i = 0; i < len; i += 2) {
diff --git a/luni/src/test/java/libcore/javax/crypto/ECDHKeyAgreementTest.java b/luni/src/test/java/libcore/javax/crypto/ECDHKeyAgreementTest.java
new file mode 100644
index 0000000..cabe5c9
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/crypto/ECDHKeyAgreementTest.java
@@ -0,0 +1,438 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.crypto;
+
+import static libcore.java.security.SignatureTest.hexToBytes;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.GeneralSecurityException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Arrays;
+import java.util.Comparator;
+
+import javax.crypto.KeyAgreement;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+
+/**
+ * Tests for all registered Elliptic Curve Diffie-Hellman {@link KeyAgreement} providers.
+ */
+public class ECDHKeyAgreementTest extends TestCase {
+    // Two key pairs and the resulting shared secret for the Known Answer Test
+    private static final byte[] KAT_PUBLIC_KEY1_X509 = hexToBytes(
+            "3059301306072a8648ce3d020106082a8648ce3d030107034200049fc2f71f85446b1371244491d83"
+            + "9cf97b5d27cedbb04d2c0058b59709df3a216e6b4ca1b2d622588c5a0e6968144a8965e816a600c"
+            + "05305a1da3df2bf02b41d1");
+    private static final byte[] KAT_PRIVATE_KEY1_PKCS8 = hexToBytes(
+            "308193020100301306072a8648ce3d020106082a8648ce3d030107047930770201010420e1e683003"
+            + "c8b963a92742e5f955ce7fddc81d0c3ae9b149d6af86a0cacb2271ca00a06082a8648ce3d030107"
+            + "a144034200049fc2f71f85446b1371244491d839cf97b5d27cedbb04d2c0058b59709df3a216e6b"
+            + "4ca1b2d622588c5a0e6968144a8965e816a600c05305a1da3df2bf02b41d1");
+
+    private static final byte[] KAT_PUBLIC_KEY2_X509 = hexToBytes(
+            "3059301306072a8648ce3d020106082a8648ce3d03010703420004358efb6d91e5bbcae21774af3f6"
+            + "d85d0848630e7e61dbeb5ac9e47036ed0f8d38c7a1d1bb249f92861c7c9153fff33f45ab5b171eb"
+            + "e8cad741125e6bb4fc6b07");
+    private static final byte[] KAT_PRIVATE_KEY2_PKCS8 = hexToBytes(
+            "308193020100301306072a8648ce3d020106082a8648ce3d0301070479307702010104202b1810a69"
+            + "e12b74d50bf0343168f705f0104f76299855268aa526fdb31e6eec0a00a06082a8648ce3d030107"
+            + "a14403420004358efb6d91e5bbcae21774af3f6d85d0848630e7e61dbeb5ac9e47036ed0f8d38c7"
+            + "a1d1bb249f92861c7c9153fff33f45ab5b171ebe8cad741125e6bb4fc6b07");
+
+    private static final byte[] KAT_SECRET =
+            hexToBytes("4faa0594c0e773eb26c8df2163af2443e88aab9578b9e1f324bc61e42d222783");
+
+    private static final ECPublicKey KAT_PUBLIC_KEY1;
+    private static final ECPrivateKey KAT_PRIVATE_KEY1;
+    private static final ECPublicKey KAT_PUBLIC_KEY2;
+    private static final ECPrivateKey KAT_PRIVATE_KEY2;
+    static {
+        try {
+            KAT_PUBLIC_KEY1 = getPublicKey(KAT_PUBLIC_KEY1_X509);
+            KAT_PRIVATE_KEY1 = getPrivateKey(KAT_PRIVATE_KEY1_PKCS8);
+            KAT_PUBLIC_KEY2 = getPublicKey(KAT_PUBLIC_KEY2_X509);
+            KAT_PRIVATE_KEY2 = getPrivateKey(KAT_PRIVATE_KEY2_PKCS8);
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to decode KAT key pairs using default provider", e);
+        }
+    }
+
+    /**
+     * Performs a known-answer test of the shared secret for all permutations of {@code Providers}
+     * of: first key pair, second key pair, and the {@code KeyAgreement}. This is to check that
+     * the {@code KeyAgreement} instances work with keys of all registered providers.
+     */
+    public void testKnownAnswer() throws Exception {
+        for (Provider keyFactoryProvider1 : getKeyFactoryProviders()) {
+            ECPrivateKey privateKey1 = getPrivateKey(KAT_PRIVATE_KEY1_PKCS8, keyFactoryProvider1);
+            ECPublicKey publicKey1 = getPublicKey(KAT_PUBLIC_KEY1_X509, keyFactoryProvider1);
+            for (Provider keyFactoryProvider2 : getKeyFactoryProviders()) {
+                ECPrivateKey privateKey2 =
+                        getPrivateKey(KAT_PRIVATE_KEY2_PKCS8, keyFactoryProvider2);
+                ECPublicKey publicKey2 =
+                        getPublicKey(KAT_PUBLIC_KEY2_X509, keyFactoryProvider2);
+                for (Provider keyAgreementProvider : getKeyAgreementProviders()) {
+                    try {
+                        testKnownAnswer(publicKey1, privateKey1, publicKey2, privateKey2,
+                                keyAgreementProvider);
+                    } catch (Throwable e) {
+                        throw new RuntimeException(getClass().getSimpleName() + ".testKnownAnswer("
+                                + keyFactoryProvider1.getName()
+                                + ", " + keyFactoryProvider2.getName()
+                                + ", " + keyAgreementProvider.getName() + ")",
+                                e);
+                    }
+                }
+            }
+        }
+    }
+
+    void testKnownAnswer(
+            ECPublicKey publicKey1, ECPrivateKey privateKey1,
+            ECPublicKey publicKey2, ECPrivateKey privateKey2,
+            Provider keyAgreementProvider) throws Exception {
+        assertTrue(Arrays.equals(
+                KAT_SECRET, generateSecret(keyAgreementProvider, privateKey1, publicKey2)));
+        assertTrue(Arrays.equals(
+                KAT_SECRET, generateSecret(keyAgreementProvider, privateKey2, publicKey1)));
+    }
+
+    public void testGetAlgorithm() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testGetAlgorithm(Provider provider) throws Exception {
+        assertEquals("ECDH", getKeyAgreement(provider).getAlgorithm());
+    }
+
+    public void testGetProvider() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testGetProvider(Provider provider) throws Exception {
+        assertSame(provider, getKeyAgreement(provider).getProvider());
+    }
+
+    public void testInit_withNullPrivateKey() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testInit_withNullPrivateKey(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        try {
+            keyAgreement.init(null);
+            fail();
+        } catch (InvalidKeyException expected) {}
+    }
+
+    public void testInit_withUnsupportedPrivateKeyType() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testInit_withUnsupportedPrivateKeyType(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        try {
+            keyAgreement.init(KAT_PUBLIC_KEY1);
+            fail();
+        } catch (InvalidKeyException expected) {}
+    }
+
+    public void testInit_withUnsupportedAlgorithmParameterSpec() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testInit_withUnsupportedAlgorithmParameterSpec(Provider provider) throws Exception {
+        try {
+            getKeyAgreement(provider).init(KAT_PRIVATE_KEY1, new ECGenParameterSpec("prime256v1"));
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+    }
+
+    public void testDoPhase_whenNotInitialized() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testDoPhase_whenNotInitialized(Provider provider) throws Exception {
+        try {
+            getKeyAgreement(provider).doPhase(KAT_PUBLIC_KEY1, true);
+            fail();
+        } catch (IllegalStateException expected) {}
+    }
+
+    public void testDoPhaseReturnsNull() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testDoPhaseReturnsNull(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY1);
+        assertNull(keyAgreement.doPhase(KAT_PUBLIC_KEY2, true));
+    }
+
+    public void testDoPhase_withPhaseWhichIsNotLast() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testDoPhase_withPhaseWhichIsNotLast(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY1);
+        try {
+            keyAgreement.doPhase(KAT_PUBLIC_KEY2, false);
+            fail();
+        } catch (IllegalStateException expected) {}
+    }
+
+    public void testDoPhase_withNullKey() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testDoPhase_withNullKey(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY1);
+        try {
+            keyAgreement.doPhase(null, true);
+            fail();
+        } catch (InvalidKeyException expected) {}
+    }
+
+    public void testDoPhase_withInvalidKeyType() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testDoPhase_withInvalidKeyType(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY1);
+        try {
+            keyAgreement.doPhase(KAT_PRIVATE_KEY1, true);
+            fail();
+        } catch (InvalidKeyException expected) {}
+    }
+
+    public void testGenerateSecret_withNullOutputBuffer() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testGenerateSecret_withNullOutputBuffer(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY1);
+        keyAgreement.doPhase(KAT_PUBLIC_KEY2, true);
+        try {
+            keyAgreement.generateSecret(null, 0);
+            fail();
+        } catch (NullPointerException expected) {}
+    }
+
+    public void testGenerateSecret_withBufferOfTheRightSize() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testGenerateSecret_withBufferOfTheRightSize(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY1);
+        keyAgreement.doPhase(KAT_PUBLIC_KEY2, true);
+
+        byte[] buffer = new byte[KAT_SECRET.length];
+        int secretLengthBytes = keyAgreement.generateSecret(buffer, 0);
+        assertEquals(KAT_SECRET.length, secretLengthBytes);
+        assertTrue(Arrays.equals(KAT_SECRET, buffer));
+    }
+
+    public void testGenerateSecret_withLargerThatNeededBuffer() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testGenerateSecret_withLargerThatNeededBuffer(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY1);
+        keyAgreement.doPhase(KAT_PUBLIC_KEY2, true);
+
+        // Place the shared secret in the middle of the larger buffer and check that only that
+        // part of the buffer is affected.
+        byte[] buffer = new byte[KAT_SECRET.length + 2];
+        buffer[0] = (byte) 0x85; // arbitrary canary value
+        buffer[buffer.length - 1] = (byte) 0x3b; // arbitrary canary value
+        int secretLengthBytes = keyAgreement.generateSecret(buffer, 1);
+        assertEquals(KAT_SECRET.length, secretLengthBytes);
+        assertEquals((byte) 0x85, buffer[0]);
+        assertEquals((byte) 0x3b, buffer[buffer.length - 1]);
+        byte[] secret = new byte[KAT_SECRET.length];
+        System.arraycopy(buffer, 1, secret, 0, secret.length);
+        assertTrue(Arrays.equals(KAT_SECRET, secret));
+    }
+
+    public void testGenerateSecret_withSmallerThanNeededBuffer() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testGenerateSecret_withSmallerThanNeededBuffer(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY1);
+        keyAgreement.doPhase(KAT_PUBLIC_KEY2, true);
+        try {
+            // Although the buffer is big enough (1024 bytes) the shared secret should be placed
+            // at offset 1020 thus leaving only 4 bytes for the secret, which is not enough.
+            keyAgreement.generateSecret(new byte[1024], 1020);
+            fail();
+        } catch (ShortBufferException expected) {}
+    }
+
+    public void testGenerateSecret_withoutBuffer() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testGenerateSecret_withoutBuffer(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY2);
+        keyAgreement.doPhase(KAT_PUBLIC_KEY1, true);
+
+        byte[] secret = keyAgreement.generateSecret();
+        assertTrue(Arrays.equals(KAT_SECRET, secret));
+    }
+
+    public void testGenerateSecret_withAlgorithm() throws Exception {
+        invokeCallingMethodForEachKeyAgreementProvider();
+    }
+
+    void testGenerateSecret_withAlgorithm(Provider provider) throws Exception {
+        KeyAgreement keyAgreement = getKeyAgreement(provider);
+        keyAgreement.init(KAT_PRIVATE_KEY2);
+        keyAgreement.doPhase(KAT_PUBLIC_KEY1, true);
+
+        SecretKey key = keyAgreement.generateSecret("AES");
+        assertEquals("AES", key.getAlgorithm());
+        // The check below will need to change if it's a hardware-backed key.
+        // We'll have to encrypt a known plaintext and check that the ciphertext is as
+        // expected.
+        assertTrue(Arrays.equals(KAT_SECRET, key.getEncoded()));
+    }
+
+    private void invokeCallingMethodForEachKeyAgreementProvider() throws Exception {
+        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
+        String callingMethodName = null;
+        for (int i = 0; i < stackTrace.length; i++) {
+            if ("invokeCallingMethodForEachKeyAgreementProvider".equals(
+                    stackTrace[i].getMethodName())) {
+                callingMethodName = stackTrace[i + 1].getMethodName();
+            }
+        }
+        if (callingMethodName == null) {
+            throw new RuntimeException("Failed to deduce calling method name from stack trace");
+        }
+
+        String invokedMethodName = callingMethodName;
+        Method method;
+        try {
+            method = getClass().getDeclaredMethod(invokedMethodName, Provider.class);
+        } catch (NoSuchMethodError e) {
+            throw new AssertionFailedError("Failed to find per-Provider test method "
+                    + getClass().getSimpleName() + "." + invokedMethodName + "(Provider)");
+        }
+
+        for (Provider provider : getKeyAgreementProviders()) {
+            try {
+                method.invoke(this, provider);
+            } catch (InvocationTargetException e) {
+                throw new RuntimeException(getClass().getSimpleName() + "." + invokedMethodName
+                        + "(provider: " + provider.getName() + ") failed",
+                        e.getCause());
+            }
+        }
+    }
+
+    private static Provider[] getKeyAgreementProviders() {
+        Provider[] providers = Security.getProviders("KeyAgreement.ECDH");
+        if (providers == null) {
+            return new Provider[0];
+        }
+        // Sort providers by name to guarantee non-determinism in the order in which providers are
+        // used in the tests.
+        return sortByName(providers);
+    }
+
+    private static Provider[] getKeyFactoryProviders() {
+        Provider[] providers = Security.getProviders("KeyFactory.EC");
+        if (providers == null) {
+            return new Provider[0];
+        }
+        // Sort providers by name to guarantee non-determinism in the order in which providers are
+        // used in the tests.
+        return sortByName(providers);
+    }
+
+    private static ECPrivateKey getPrivateKey(byte[] pkcs8EncodedKey, Provider provider)
+            throws GeneralSecurityException {
+        KeyFactory keyFactory = KeyFactory.getInstance("EC", provider);
+        return (ECPrivateKey) keyFactory.generatePrivate(new PKCS8EncodedKeySpec(pkcs8EncodedKey));
+    }
+
+    private static ECPublicKey getPublicKey(byte[] x509EncodedKey, Provider provider)
+            throws GeneralSecurityException {
+        KeyFactory keyFactory = KeyFactory.getInstance("EC", provider);
+        return (ECPublicKey) keyFactory.generatePublic(new X509EncodedKeySpec(x509EncodedKey));
+    }
+
+    private static ECPrivateKey getPrivateKey(byte[] pkcs8EncodedKey)
+            throws GeneralSecurityException {
+        KeyFactory keyFactory = KeyFactory.getInstance("EC");
+        return (ECPrivateKey) keyFactory.generatePrivate(new PKCS8EncodedKeySpec(pkcs8EncodedKey));
+    }
+
+    private static ECPublicKey getPublicKey(byte[] x509EncodedKey)
+            throws GeneralSecurityException {
+        KeyFactory keyFactory = KeyFactory.getInstance("EC");
+        return (ECPublicKey) keyFactory.generatePublic(new X509EncodedKeySpec(x509EncodedKey));
+    }
+
+    private static KeyAgreement getKeyAgreement(Provider provider) throws NoSuchAlgorithmException {
+        return KeyAgreement.getInstance("ECDH", provider);
+    }
+
+    private static byte[] generateSecret(
+            Provider keyAgreementProvider, PrivateKey privateKey, PublicKey publicKey)
+            throws GeneralSecurityException {
+        KeyAgreement keyAgreement = getKeyAgreement(keyAgreementProvider);
+        keyAgreement.init(privateKey);
+        keyAgreement.doPhase(publicKey, true);
+        return keyAgreement.generateSecret();
+    }
+
+    private static Provider[] sortByName(Provider[] providers) {
+        Arrays.sort(providers, new Comparator<Provider>() {
+            @Override
+            public int compare(Provider lhs, Provider rhs) {
+                return lhs.getName().compareTo(rhs.getName());
+            }
+        });
+        return providers;
+    }
+}
