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 17 package android.security.keystore2; 18 19 import android.annotation.NonNull; 20 import android.hardware.security.keymint.KeyParameter; 21 import android.security.keymaster.KeymasterDefs; 22 import android.security.keystore.KeyProperties; 23 24 import java.security.InvalidKeyException; 25 import java.security.SignatureSpi; 26 import java.util.List; 27 28 /** 29 * Base class for {@link SignatureSpi} providing Android KeyStore backed RSA signatures. 30 * 31 * @hide 32 */ 33 abstract class AndroidKeyStoreRSASignatureSpi extends AndroidKeyStoreSignatureSpiBase { 34 35 abstract static class PKCS1Padding extends AndroidKeyStoreRSASignatureSpi { PKCS1Padding(int keymasterDigest)36 PKCS1Padding(int keymasterDigest) { 37 super(keymasterDigest, KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN); 38 } 39 40 @Override getAdditionalEntropyAmountForSign()41 protected final int getAdditionalEntropyAmountForSign() { 42 // No entropy required for this deterministic signature scheme. 43 return 0; 44 } 45 } 46 47 public static final class NONEWithPKCS1Padding extends PKCS1Padding { NONEWithPKCS1Padding()48 public NONEWithPKCS1Padding() { 49 super(KeymasterDefs.KM_DIGEST_NONE); 50 } 51 @Override getAlgorithm()52 protected String getAlgorithm() { 53 return "NONEwithRSA"; 54 } 55 } 56 57 public static final class MD5WithPKCS1Padding extends PKCS1Padding { MD5WithPKCS1Padding()58 public MD5WithPKCS1Padding() { 59 super(KeymasterDefs.KM_DIGEST_MD5); 60 } 61 @Override getAlgorithm()62 protected String getAlgorithm() { 63 return "MD5withRSA"; 64 } 65 } 66 67 public static final class SHA1WithPKCS1Padding extends PKCS1Padding { SHA1WithPKCS1Padding()68 public SHA1WithPKCS1Padding() { 69 super(KeymasterDefs.KM_DIGEST_SHA1); 70 } 71 @Override getAlgorithm()72 protected String getAlgorithm() { 73 return "SHA1withRSA"; 74 } 75 } 76 77 public static final class SHA224WithPKCS1Padding extends PKCS1Padding { SHA224WithPKCS1Padding()78 public SHA224WithPKCS1Padding() { 79 super(KeymasterDefs.KM_DIGEST_SHA_2_224); 80 } 81 @Override getAlgorithm()82 protected String getAlgorithm() { 83 return "SHA224withRSA"; 84 } 85 } 86 87 public static final class SHA256WithPKCS1Padding extends PKCS1Padding { SHA256WithPKCS1Padding()88 public SHA256WithPKCS1Padding() { 89 super(KeymasterDefs.KM_DIGEST_SHA_2_256); 90 } 91 @Override getAlgorithm()92 protected String getAlgorithm() { 93 return "SHA256withRSA"; 94 } 95 } 96 97 public static final class SHA384WithPKCS1Padding extends PKCS1Padding { SHA384WithPKCS1Padding()98 public SHA384WithPKCS1Padding() { 99 super(KeymasterDefs.KM_DIGEST_SHA_2_384); 100 } 101 @Override getAlgorithm()102 protected String getAlgorithm() { 103 return "SHA384withRSA"; 104 } 105 } 106 107 public static final class SHA512WithPKCS1Padding extends PKCS1Padding { SHA512WithPKCS1Padding()108 public SHA512WithPKCS1Padding() { 109 super(KeymasterDefs.KM_DIGEST_SHA_2_512); 110 } 111 @Override getAlgorithm()112 protected String getAlgorithm() { 113 return "SHA512withRSA"; 114 } 115 } 116 117 abstract static class PSSPadding extends AndroidKeyStoreRSASignatureSpi { 118 private static final int SALT_LENGTH_BYTES = 20; 119 PSSPadding(int keymasterDigest)120 PSSPadding(int keymasterDigest) { 121 super(keymasterDigest, KeymasterDefs.KM_PAD_RSA_PSS); 122 } 123 124 @Override getAdditionalEntropyAmountForSign()125 protected final int getAdditionalEntropyAmountForSign() { 126 return SALT_LENGTH_BYTES; 127 } 128 } 129 130 public static final class SHA1WithPSSPadding extends PSSPadding { SHA1WithPSSPadding()131 public SHA1WithPSSPadding() { 132 super(KeymasterDefs.KM_DIGEST_SHA1); 133 } 134 @Override getAlgorithm()135 protected String getAlgorithm() { 136 return "SHA1withRSA/PSS"; 137 } 138 } 139 140 public static final class SHA224WithPSSPadding extends PSSPadding { SHA224WithPSSPadding()141 public SHA224WithPSSPadding() { 142 super(KeymasterDefs.KM_DIGEST_SHA_2_224); 143 } 144 @Override getAlgorithm()145 protected String getAlgorithm() { 146 return "SHA224withRSA/PSS"; 147 } 148 } 149 150 public static final class SHA256WithPSSPadding extends PSSPadding { SHA256WithPSSPadding()151 public SHA256WithPSSPadding() { 152 super(KeymasterDefs.KM_DIGEST_SHA_2_256); 153 } 154 @Override getAlgorithm()155 protected String getAlgorithm() { 156 return "SHA256withRSA/PSS"; 157 } 158 } 159 160 public static final class SHA384WithPSSPadding extends PSSPadding { SHA384WithPSSPadding()161 public SHA384WithPSSPadding() { 162 super(KeymasterDefs.KM_DIGEST_SHA_2_384); 163 } 164 @Override getAlgorithm()165 protected String getAlgorithm() { 166 return "SHA384withRSA/PSS"; 167 } 168 } 169 170 public static final class SHA512WithPSSPadding extends PSSPadding { SHA512WithPSSPadding()171 public SHA512WithPSSPadding() { 172 super(KeymasterDefs.KM_DIGEST_SHA_2_512); 173 } 174 @Override getAlgorithm()175 protected String getAlgorithm() { 176 return "SHA512withRSA/PSS"; 177 } 178 } 179 180 private final int mKeymasterDigest; 181 private final int mKeymasterPadding; 182 AndroidKeyStoreRSASignatureSpi(int keymasterDigest, int keymasterPadding)183 AndroidKeyStoreRSASignatureSpi(int keymasterDigest, int keymasterPadding) { 184 mKeymasterDigest = keymasterDigest; 185 mKeymasterPadding = keymasterPadding; 186 } 187 188 @Override initKey(AndroidKeyStoreKey key)189 protected final void initKey(AndroidKeyStoreKey key) throws InvalidKeyException { 190 if (!KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(key.getAlgorithm())) { 191 throw new InvalidKeyException("Unsupported key algorithm: " + key.getAlgorithm() 192 + ". Only" + KeyProperties.KEY_ALGORITHM_RSA + " supported"); 193 } 194 super.initKey(key); 195 } 196 197 @Override resetAll()198 protected final void resetAll() { 199 super.resetAll(); 200 } 201 202 @Override resetWhilePreservingInitState()203 protected final void resetWhilePreservingInitState() { 204 super.resetWhilePreservingInitState(); 205 } 206 207 @Override addAlgorithmSpecificParametersToBegin( @onNull List<KeyParameter> parameters)208 protected final void addAlgorithmSpecificParametersToBegin( 209 @NonNull List<KeyParameter> parameters) { 210 parameters.add(KeyStore2ParameterUtils.makeEnum( 211 KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA 212 )); 213 parameters.add(KeyStore2ParameterUtils.makeEnum( 214 KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest 215 )); 216 parameters.add(KeyStore2ParameterUtils.makeEnum( 217 KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding 218 )); 219 } 220 } 221