1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.security.keystore; 18 19import android.annotation.NonNull; 20import android.security.keymaster.KeymasterArguments; 21import android.security.keymaster.KeymasterDefs; 22 23import java.security.InvalidKeyException; 24import java.security.SignatureSpi; 25 26/** 27 * Base class for {@link SignatureSpi} providing Android KeyStore backed RSA signatures. 28 * 29 * @hide 30 */ 31abstract class AndroidKeyStoreRSASignatureSpi extends AndroidKeyStoreSignatureSpiBase { 32 33 abstract static class PKCS1Padding extends AndroidKeyStoreRSASignatureSpi { 34 PKCS1Padding(int keymasterDigest) { 35 super(keymasterDigest, KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN); 36 } 37 38 @Override 39 protected final int getAdditionalEntropyAmountForSign() { 40 // No entropy required for this deterministic signature scheme. 41 return 0; 42 } 43 } 44 45 public static final class NONEWithPKCS1Padding extends PKCS1Padding { 46 public NONEWithPKCS1Padding() { 47 super(KeymasterDefs.KM_DIGEST_NONE); 48 } 49 } 50 51 public static final class MD5WithPKCS1Padding extends PKCS1Padding { 52 public MD5WithPKCS1Padding() { 53 super(KeymasterDefs.KM_DIGEST_MD5); 54 } 55 } 56 57 public static final class SHA1WithPKCS1Padding extends PKCS1Padding { 58 public SHA1WithPKCS1Padding() { 59 super(KeymasterDefs.KM_DIGEST_SHA1); 60 } 61 } 62 63 public static final class SHA224WithPKCS1Padding extends PKCS1Padding { 64 public SHA224WithPKCS1Padding() { 65 super(KeymasterDefs.KM_DIGEST_SHA_2_224); 66 } 67 } 68 69 public static final class SHA256WithPKCS1Padding extends PKCS1Padding { 70 public SHA256WithPKCS1Padding() { 71 super(KeymasterDefs.KM_DIGEST_SHA_2_256); 72 } 73 } 74 75 public static final class SHA384WithPKCS1Padding extends PKCS1Padding { 76 public SHA384WithPKCS1Padding() { 77 super(KeymasterDefs.KM_DIGEST_SHA_2_384); 78 } 79 } 80 81 public static final class SHA512WithPKCS1Padding extends PKCS1Padding { 82 public SHA512WithPKCS1Padding() { 83 super(KeymasterDefs.KM_DIGEST_SHA_2_512); 84 } 85 } 86 87 abstract static class PSSPadding extends AndroidKeyStoreRSASignatureSpi { 88 private static final int SALT_LENGTH_BYTES = 20; 89 90 PSSPadding(int keymasterDigest) { 91 super(keymasterDigest, KeymasterDefs.KM_PAD_RSA_PSS); 92 } 93 94 @Override 95 protected final int getAdditionalEntropyAmountForSign() { 96 return SALT_LENGTH_BYTES; 97 } 98 } 99 100 public static final class SHA1WithPSSPadding extends PSSPadding { 101 public SHA1WithPSSPadding() { 102 super(KeymasterDefs.KM_DIGEST_SHA1); 103 } 104 } 105 106 public static final class SHA224WithPSSPadding extends PSSPadding { 107 public SHA224WithPSSPadding() { 108 super(KeymasterDefs.KM_DIGEST_SHA_2_224); 109 } 110 } 111 112 public static final class SHA256WithPSSPadding extends PSSPadding { 113 public SHA256WithPSSPadding() { 114 super(KeymasterDefs.KM_DIGEST_SHA_2_256); 115 } 116 } 117 118 public static final class SHA384WithPSSPadding extends PSSPadding { 119 public SHA384WithPSSPadding() { 120 super(KeymasterDefs.KM_DIGEST_SHA_2_384); 121 } 122 } 123 124 public static final class SHA512WithPSSPadding extends PSSPadding { 125 public SHA512WithPSSPadding() { 126 super(KeymasterDefs.KM_DIGEST_SHA_2_512); 127 } 128 } 129 130 private final int mKeymasterDigest; 131 private final int mKeymasterPadding; 132 133 AndroidKeyStoreRSASignatureSpi(int keymasterDigest, int keymasterPadding) { 134 mKeymasterDigest = keymasterDigest; 135 mKeymasterPadding = keymasterPadding; 136 } 137 138 @Override 139 protected final void initKey(AndroidKeyStoreKey key) throws InvalidKeyException { 140 if (!KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(key.getAlgorithm())) { 141 throw new InvalidKeyException("Unsupported key algorithm: " + key.getAlgorithm() 142 + ". Only" + KeyProperties.KEY_ALGORITHM_RSA + " supported"); 143 } 144 super.initKey(key); 145 } 146 147 @Override 148 protected final void resetAll() { 149 super.resetAll(); 150 } 151 152 @Override 153 protected final void resetWhilePreservingInitState() { 154 super.resetWhilePreservingInitState(); 155 } 156 157 @Override 158 protected final void addAlgorithmSpecificParametersToBegin( 159 @NonNull KeymasterArguments keymasterArgs) { 160 keymasterArgs.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA); 161 keymasterArgs.addEnum(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest); 162 keymasterArgs.addEnum(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding); 163 } 164} 165