Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7b4d6dc authored by Shawn Willden's avatar Shawn Willden Committed by Android (Google) Code Review
Browse files

Merge "Keymaster digest/padding NONE no longer means ANY." into mnc-dev

parents b8040265 e4928a29
Loading
Loading
Loading
Loading
+31 −35
Original line number Diff line number Diff line
@@ -63,7 +63,6 @@ import java.security.spec.ECGenParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -215,7 +214,14 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
                                    KeyProperties.PURPOSE_SIGN
                                    | KeyProperties.PURPOSE_VERIFY);
                            // Authorized to be used with any digest (including no digest).
                            specBuilder.setDigests(KeyProperties.DIGEST_NONE);
                            // MD5 was never offered for Android Keystore for ECDSA.
                            specBuilder.setDigests(
                                    KeyProperties.DIGEST_NONE,
                                    KeyProperties.DIGEST_SHA1,
                                    KeyProperties.DIGEST_SHA224,
                                    KeyProperties.DIGEST_SHA256,
                                    KeyProperties.DIGEST_SHA384,
                                    KeyProperties.DIGEST_SHA512);
                            break;
                        case KeymasterDefs.KM_ALGORITHM_RSA:
                            specBuilder = new KeyGenParameterSpec.Builder(
@@ -225,11 +231,23 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
                                    | KeyProperties.PURPOSE_SIGN
                                    | KeyProperties.PURPOSE_VERIFY);
                            // Authorized to be used with any digest (including no digest).
                            specBuilder.setDigests(KeyProperties.DIGEST_NONE);
                            specBuilder.setDigests(
                                    KeyProperties.DIGEST_NONE,
                                    KeyProperties.DIGEST_MD5,
                                    KeyProperties.DIGEST_SHA1,
                                    KeyProperties.DIGEST_SHA224,
                                    KeyProperties.DIGEST_SHA256,
                                    KeyProperties.DIGEST_SHA384,
                                    KeyProperties.DIGEST_SHA512);
                            // Authorized to be used with any encryption and signature padding
                            // scheme (including no padding).
                            // schemes (including no padding).
                            specBuilder.setEncryptionPaddings(
                                    KeyProperties.ENCRYPTION_PADDING_NONE);
                                    KeyProperties.ENCRYPTION_PADDING_NONE,
                                    KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1,
                                    KeyProperties.ENCRYPTION_PADDING_RSA_OAEP);
                            specBuilder.setSignaturePaddings(
                                    KeyProperties.SIGNATURE_PADDING_RSA_PKCS1,
                                    KeyProperties.SIGNATURE_PADDING_RSA_PSS);
                            // Disable randomized encryption requirement to support encryption
                            // padding NONE above.
                            specBuilder.setRandomizedEncryptionRequired(false);
@@ -724,27 +742,11 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
                // We use Bouncy Castle to generate self-signed RSA certificates. Bouncy Castle
                // only supports RSA certificates signed using PKCS#1 padding scheme. The key needs
                // to be authorized for PKCS#1 padding or padding NONE which means any padding.
                boolean pkcs1SignaturePaddingSupported = false;
                for (int keymasterPadding : KeyProperties.SignaturePadding.allToKeymaster(
                        spec.getSignaturePaddings())) {
                    if ((keymasterPadding == KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN)
                            || (keymasterPadding == KeymasterDefs.KM_PAD_NONE)) {
                        pkcs1SignaturePaddingSupported = true;
                        break;
                    }
                }
                if (!pkcs1SignaturePaddingSupported) {
                    // Keymaster doesn't distinguish between encryption padding NONE and signature
                    // padding NONE. In the Android Keystore API only encryption padding NONE is
                    // exposed.
                    for (int keymasterPadding : KeyProperties.EncryptionPadding.allToKeymaster(
                            spec.getEncryptionPaddings())) {
                        if (keymasterPadding == KeymasterDefs.KM_PAD_NONE) {
                            pkcs1SignaturePaddingSupported = true;
                            break;
                        }
                    }
                }
                boolean pkcs1SignaturePaddingSupported =
                        com.android.internal.util.ArrayUtils.contains(
                                KeyProperties.SignaturePadding.allToKeymaster(
                                        spec.getSignaturePaddings()),
                                KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN);
                if (!pkcs1SignaturePaddingSupported) {
                    // Key not authorized for PKCS#1 signature padding -- can't sign
                    return null;
@@ -803,14 +805,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
                : KeyProperties.Digest.allToKeymaster(supportedSignatureDigests)) {
            supportedKeymasterSignatureDigests.add(keymasterDigest);
        }
        if (authorizedKeymasterKeyDigests.contains(KeymasterDefs.KM_DIGEST_NONE)) {
            // Key is authorized to be used with any digest
            return supportedKeymasterSignatureDigests;
        } else {
            // Key is authorized to be used only with specific digests.
        Set<Integer> result = new HashSet<Integer>(supportedKeymasterSignatureDigests);
        result.retainAll(authorizedKeymasterKeyDigests);
        return result;
    }
}
}
+26 −7
Original line number Diff line number Diff line
@@ -292,7 +292,14 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
                    new KeyProtection.Builder(
                            KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY);
            // Authorized to be used with any digest (including no digest).
            specBuilder.setDigests(KeyProperties.DIGEST_NONE);
            // MD5 was never offered for Android Keystore for ECDSA.
            specBuilder.setDigests(
                    KeyProperties.DIGEST_NONE,
                    KeyProperties.DIGEST_SHA1,
                    KeyProperties.DIGEST_SHA224,
                    KeyProperties.DIGEST_SHA256,
                    KeyProperties.DIGEST_SHA384,
                    KeyProperties.DIGEST_SHA512);
        } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
            specBuilder =
                    new KeyProtection.Builder(
@@ -301,13 +308,25 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
                            | KeyProperties.PURPOSE_SIGN
                            | KeyProperties.PURPOSE_VERIFY);
            // Authorized to be used with any digest (including no digest).
            specBuilder.setDigests(KeyProperties.DIGEST_NONE);
            // Authorized to be used with any encryption and signature padding scheme (including no
            // padding).
            specBuilder.setDigests(
                    KeyProperties.DIGEST_NONE,
                    KeyProperties.DIGEST_MD5,
                    KeyProperties.DIGEST_SHA1,
                    KeyProperties.DIGEST_SHA224,
                    KeyProperties.DIGEST_SHA256,
                    KeyProperties.DIGEST_SHA384,
                    KeyProperties.DIGEST_SHA512);
            // Authorized to be used with any encryption and signature padding
            // schemes (including no padding).
            specBuilder.setEncryptionPaddings(
                    KeyProperties.ENCRYPTION_PADDING_NONE);
            // Disable randomized encryption requirement to support encryption padding NONE
            // above.
                    KeyProperties.ENCRYPTION_PADDING_NONE,
                    KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1,
                    KeyProperties.ENCRYPTION_PADDING_RSA_OAEP);
            specBuilder.setSignaturePaddings(
                    KeyProperties.SIGNATURE_PADDING_RSA_PKCS1,
                    KeyProperties.SIGNATURE_PADDING_RSA_PSS);
            // Disable randomized encryption requirement to support encryption
            // padding NONE above.
            specBuilder.setRandomizedEncryptionRequired(false);
        } else {
            throw new KeyStoreException("Unsupported key algorithm: " + keyAlgorithm);
+6 −6
Original line number Diff line number Diff line
@@ -65,17 +65,16 @@ import javax.security.auth.x500.X500Principal;
 *
 * <p>NOTE: If a private key is not authorized to sign the self-signed certificate, then the
 * certificate will be created with an invalid signature which will not verify. Such a certificate
 * is still useful because it provides access to the public key. To generate a valid
 * signature for the certificate the key needs to be authorized for all of the following:
 * is still useful because it provides access to the public key. To generate a valid signature for
 * the certificate the key needs to be authorized for all of the following:
 * <ul>
 * <li>{@link KeyProperties#PURPOSE_SIGN},</li>
 * <li>operation without requiring the user to be authenticated (see
 * {@link Builder#setUserAuthenticationRequired(boolean)}),</li>
 * <li>signing/origination at this moment in time (see {@link Builder#setKeyValidityStart(Date)}
 * and {@link Builder#setKeyValidityForOriginationEnd(Date)}),</li>
 * <li>suitable digest or {@link KeyProperties#DIGEST_NONE},</li>
 * <li>(RSA keys only) padding scheme {@link KeyProperties#SIGNATURE_PADDING_RSA_PKCS1} or
 * {@link KeyProperties#ENCRYPTION_PADDING_NONE}.</li>
 * <li>suitable digest,</li>
 * <li>(RSA keys only) padding scheme {@link KeyProperties#SIGNATURE_PADDING_RSA_PKCS1}.</li>
 * </ul>
 *
 * <p>NOTE: The key material of the generated symmetric and private keys is not accessible. The key
@@ -668,7 +667,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
         *
         * <p>For RSA private keys used by TLS/SSL servers to authenticate themselves to clients it
         * is usually necessary to authorize the use of no/any padding
         * ({@link KeyProperties#ENCRYPTION_PADDING_NONE}). This is because RSA decryption is
         * ({@link KeyProperties#ENCRYPTION_PADDING_NONE}) and/or PKCS#1 encryption padding
         * ({@link KeyProperties#ENCRYPTION_PADDING_RSA_PKCS1}). This is because RSA decryption is
         * required by some cipher suites, and some stacks request decryption using no padding
         * whereas others request PKCS#1 padding.
         *
+0 −6
Original line number Diff line number Diff line
@@ -364,9 +364,6 @@ public abstract class KeyProperties {

    /**
     * No encryption padding.
     *
     * <p><b>NOTE</b>: If a key is authorized to be used with no padding, then it can be used with
     * any padding scheme, both for encryption and signing.
     */
    public static final String ENCRYPTION_PADDING_NONE = "NoPadding";

@@ -513,9 +510,6 @@ public abstract class KeyProperties {

    /**
     * No digest: sign/authenticate the raw message.
     *
     * <p><b>NOTE</b>: If a key is authorized to be used with no digest, then it can be used with
     * any digest.
     */
    public static final String DIGEST_NONE = "NONE";

+2 −1
Original line number Diff line number Diff line
@@ -386,7 +386,8 @@ public final class KeyProtection implements ProtectionParameter {
         *
         * <p>For RSA private keys used by TLS/SSL servers to authenticate themselves to clients it
         * is usually necessary to authorize the use of no/any padding
         * ({@link KeyProperties#ENCRYPTION_PADDING_NONE}). This is because RSA decryption is
         * ({@link KeyProperties#ENCRYPTION_PADDING_NONE}) and/or PKCS#1 encryption padding
         * ({@link KeyProperties#ENCRYPTION_PADDING_RSA_PKCS1}). This is because RSA decryption is
         * required by some cipher suites, and some stacks request decryption using no padding
         * whereas others request PKCS#1 padding.
         *