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

Commit f26ddd4c authored by Alex Klyubin's avatar Alex Klyubin Committed by Android Git Automerger
Browse files

am 9440a6e6: Merge "Support RSA encrypt using private key and PKCS#1 paddding." into mnc-dev

* commit '9440a6e6':
  Support RSA encrypt using private key and PKCS#1 paddding.
parents 829c2f71 9440a6e6
Loading
Loading
Loading
Loading
+15 −0
Original line number Original line Diff line number Diff line
@@ -731,6 +731,21 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
        return mMainDataStreamer.getProducedOutputSizeBytes();
        return mMainDataStreamer.getProducedOutputSizeBytes();
    }
    }


    static String opmodeToString(int opmode) {
        switch (opmode) {
            case Cipher.ENCRYPT_MODE:
                return "ENCRYPT_MODE";
            case Cipher.DECRYPT_MODE:
                return "DECRYPT_MODE";
            case Cipher.WRAP_MODE:
                return "WRAP_MODE";
            case Cipher.UNWRAP_MODE:
                return "UNWRAP_MODE";
            default:
                return String.valueOf(opmode);
        }
    }

    // The methods below need to be implemented by subclasses.
    // The methods below need to be implemented by subclasses.


    /**
    /**
+51 −18
Original line number Original line Diff line number Diff line
@@ -60,9 +60,10 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
        }
        }


        @Override
        @Override
        protected boolean isEncryptingUsingPrivateKeyPermitted() {
        protected boolean adjustConfigForEncryptingWithPrivateKey() {
            // RSA encryption with no padding using private key is is a way to implement raw RSA
            // RSA encryption with no padding using private key is a way to implement raw RSA
            // signatures. We have to support this.
            // signatures which JCA does not expose via Signature. We thus have to support this.
            setKeymasterPurposeOverride(KeymasterDefs.KM_PURPOSE_SIGN);
            return true;
            return true;
        }
        }


@@ -197,6 +198,15 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
            super(KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
            super(KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
        }
        }


        @Override
        protected boolean adjustConfigForEncryptingWithPrivateKey() {
            // RSA encryption with PCKS#1 padding using private key is a way to implement RSA
            // signatures with PKCS#1 padding. We have to support this for legacy reasons.
            setKeymasterPurposeOverride(KeymasterDefs.KM_PURPOSE_SIGN);
            setKeymasterPaddingOverride(KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN);
            return true;
        }

        @Override
        @Override
        protected void initAlgorithmSpecificParameters() throws InvalidKeyException {}
        protected void initAlgorithmSpecificParameters() throws InvalidKeyException {}


@@ -425,6 +435,7 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
    }
    }


    private final int mKeymasterPadding;
    private final int mKeymasterPadding;
    private int mKeymasterPaddingOverride;


    private int mModulusSizeBytes = -1;
    private int mModulusSizeBytes = -1;


@@ -458,20 +469,15 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
                    // Permitted
                    // Permitted
                    break;
                    break;
                case Cipher.ENCRYPT_MODE:
                case Cipher.ENCRYPT_MODE:
                    if (!isEncryptingUsingPrivateKeyPermitted()) {
                case Cipher.WRAP_MODE:
                    if (!adjustConfigForEncryptingWithPrivateKey()) {
                        throw new InvalidKeyException(
                        throw new InvalidKeyException(
                                "RSA private keys cannot be used with Cipher.ENCRYPT_MODE"
                                "RSA private keys cannot be used with " + opmodeToString(opmode)
                                + " and padding "
                                + KeyProperties.EncryptionPadding.fromKeymaster(mKeymasterPadding)
                                + ". Only RSA public keys supported for this mode");
                                + ". Only RSA public keys supported for this mode");
                    }
                    }
                    // JCA doesn't provide a way to generate raw RSA signatures (with arbitrary
                    // padding). Thus, encrypting with private key is used instead.
                    setKeymasterPurposeOverride(KeymasterDefs.KM_PURPOSE_SIGN);
                    break;
                    break;
                case Cipher.WRAP_MODE:
                    throw new InvalidKeyException(
                            "RSA private keys cannot be used with Cipher.WRAP_MODE"
                            + ". Only RSA public keys supported for this mode");
                    // break;
                default:
                default:
                    throw new InvalidKeyException(
                    throw new InvalidKeyException(
                            "RSA private keys cannot be used with opmode: " + opmode);
                            "RSA private keys cannot be used with opmode: " + opmode);
@@ -485,12 +491,15 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
                    break;
                    break;
                case Cipher.DECRYPT_MODE:
                case Cipher.DECRYPT_MODE:
                case Cipher.UNWRAP_MODE:
                case Cipher.UNWRAP_MODE:
                    throw new InvalidKeyException("RSA public keys cannot be used with opmode: "
                    throw new InvalidKeyException(
                            + opmode + ". Only RSA private keys supported for this opmode.");
                            "RSA public keys cannot be used with " + opmodeToString(opmode)
                            + " and padding "
                            + KeyProperties.EncryptionPadding.fromKeymaster(mKeymasterPadding)
                            + ". Only RSA private keys supported for this opmode.");
                    // break;
                    // break;
                default:
                default:
                    throw new InvalidKeyException(
                    throw new InvalidKeyException(
                            "RSA public keys cannot be used with opmode: " + opmode);
                            "RSA public keys cannot be used with " + opmodeToString(opmode));
            }
            }
        }
        }


@@ -511,13 +520,22 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
        setKey(keystoreKey);
        setKey(keystoreKey);
    }
    }


    protected boolean isEncryptingUsingPrivateKeyPermitted() {
    /**
     * Adjusts the configuration of this cipher for encrypting using the private key.
     *
     * <p>The default implementation does nothing and refuses to adjust the configuration.
     *
     * @return {@code true} if the configuration has been adjusted, {@code false} if encrypting
     *         using private key is not permitted for this cipher.
     */
    protected boolean adjustConfigForEncryptingWithPrivateKey() {
        return false;
        return false;
    }
    }


    @Override
    @Override
    protected final void resetAll() {
    protected final void resetAll() {
        mModulusSizeBytes = -1;
        mModulusSizeBytes = -1;
        mKeymasterPaddingOverride = -1;
        super.resetAll();
        super.resetAll();
    }
    }


@@ -530,7 +548,11 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
    protected void addAlgorithmSpecificParametersToBegin(
    protected void addAlgorithmSpecificParametersToBegin(
            @NonNull KeymasterArguments keymasterArgs) {
            @NonNull KeymasterArguments keymasterArgs) {
        keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
        keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
        keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding);
        int keymasterPadding = getKeymasterPaddingOverride();
        if (keymasterPadding == -1) {
            keymasterPadding = mKeymasterPadding;
        }
        keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, keymasterPadding);
        int purposeOverride = getKeymasterPurposeOverride();
        int purposeOverride = getKeymasterPurposeOverride();
        if ((purposeOverride != -1)
        if ((purposeOverride != -1)
                && ((purposeOverride == KeymasterDefs.KM_PURPOSE_SIGN)
                && ((purposeOverride == KeymasterDefs.KM_PURPOSE_SIGN)
@@ -568,4 +590,15 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
        }
        }
        return mModulusSizeBytes;
        return mModulusSizeBytes;
    }
    }

    /**
     * Overrides the default padding of the crypto operation.
     */
    protected final void setKeymasterPaddingOverride(int keymasterPadding) {
        mKeymasterPaddingOverride = keymasterPadding;
    }

    protected final int getKeymasterPaddingOverride() {
        return mKeymasterPaddingOverride;
    }
}
}