/* * Copyright (C) 2015 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 android.security.keystore; import android.annotation.NonNull; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterDefs; import java.security.InvalidKeyException; import java.security.SignatureSpi; /** * Base class for {@link SignatureSpi} providing Android KeyStore backed RSA signatures. * * @hide */ abstract class AndroidKeyStoreRSASignatureSpi extends AndroidKeyStoreSignatureSpiBase { abstract static class PKCS1Padding extends AndroidKeyStoreRSASignatureSpi { PKCS1Padding(int keymasterDigest) { super(keymasterDigest, KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN); } @Override protected final int getAdditionalEntropyAmountForSign() { // No entropy required for this deterministic signature scheme. return 0; } } public static final class NONEWithPKCS1Padding extends PKCS1Padding { public NONEWithPKCS1Padding() { super(KeymasterDefs.KM_DIGEST_NONE); } } public static final class MD5WithPKCS1Padding extends PKCS1Padding { public MD5WithPKCS1Padding() { super(KeymasterDefs.KM_DIGEST_MD5); } } public static final class SHA1WithPKCS1Padding extends PKCS1Padding { public SHA1WithPKCS1Padding() { super(KeymasterDefs.KM_DIGEST_SHA1); } } public static final class SHA224WithPKCS1Padding extends PKCS1Padding { public SHA224WithPKCS1Padding() { super(KeymasterDefs.KM_DIGEST_SHA_2_224); } } public static final class SHA256WithPKCS1Padding extends PKCS1Padding { public SHA256WithPKCS1Padding() { super(KeymasterDefs.KM_DIGEST_SHA_2_256); } } public static final class SHA384WithPKCS1Padding extends PKCS1Padding { public SHA384WithPKCS1Padding() { super(KeymasterDefs.KM_DIGEST_SHA_2_384); } } public static final class SHA512WithPKCS1Padding extends PKCS1Padding { public SHA512WithPKCS1Padding() { super(KeymasterDefs.KM_DIGEST_SHA_2_512); } } abstract static class PSSPadding extends AndroidKeyStoreRSASignatureSpi { private static final int SALT_LENGTH_BYTES = 20; PSSPadding(int keymasterDigest) { super(keymasterDigest, KeymasterDefs.KM_PAD_RSA_PSS); } @Override protected final int getAdditionalEntropyAmountForSign() { return SALT_LENGTH_BYTES; } } public static final class SHA1WithPSSPadding extends PSSPadding { public SHA1WithPSSPadding() { super(KeymasterDefs.KM_DIGEST_SHA1); } } public static final class SHA224WithPSSPadding extends PSSPadding { public SHA224WithPSSPadding() { super(KeymasterDefs.KM_DIGEST_SHA_2_224); } } public static final class SHA256WithPSSPadding extends PSSPadding { public SHA256WithPSSPadding() { super(KeymasterDefs.KM_DIGEST_SHA_2_256); } } public static final class SHA384WithPSSPadding extends PSSPadding { public SHA384WithPSSPadding() { super(KeymasterDefs.KM_DIGEST_SHA_2_384); } } public static final class SHA512WithPSSPadding extends PSSPadding { public SHA512WithPSSPadding() { super(KeymasterDefs.KM_DIGEST_SHA_2_512); } } private final int mKeymasterDigest; private final int mKeymasterPadding; AndroidKeyStoreRSASignatureSpi(int keymasterDigest, int keymasterPadding) { mKeymasterDigest = keymasterDigest; mKeymasterPadding = keymasterPadding; } @Override protected final void initKey(AndroidKeyStoreKey key) throws InvalidKeyException { if (!KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(key.getAlgorithm())) { throw new InvalidKeyException("Unsupported key algorithm: " + key.getAlgorithm() + ". Only" + KeyProperties.KEY_ALGORITHM_RSA + " supported"); } super.initKey(key); } @Override protected final void resetAll() { super.resetAll(); } @Override protected final void resetWhilePreservingInitState() { super.resetWhilePreservingInitState(); } @Override protected final void addAlgorithmSpecificParametersToBegin( @NonNull KeymasterArguments keymasterArgs) { keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA); keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest); keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding); } }