• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.security.keymaster.KeymasterDefs;
20 
21 import java.security.AlgorithmParameters;
22 import java.security.NoSuchAlgorithmException;
23 import java.security.spec.ECGenParameterSpec;
24 import java.security.spec.ECParameterSpec;
25 import java.security.spec.InvalidParameterSpecException;
26 
27 /**
28  * @hide
29  */
30 public final class KeymasterUtils {
31 
KeymasterUtils()32     private KeymasterUtils() {}
33 
34     /** @hide */
getDigestOutputSizeBits(int keymasterDigest)35     static int getDigestOutputSizeBits(int keymasterDigest) {
36         switch (keymasterDigest) {
37             case KeymasterDefs.KM_DIGEST_NONE:
38                 return -1;
39             case KeymasterDefs.KM_DIGEST_MD5:
40                 return 128;
41             case KeymasterDefs.KM_DIGEST_SHA1:
42                 return 160;
43             case KeymasterDefs.KM_DIGEST_SHA_2_224:
44                 return 224;
45             case KeymasterDefs.KM_DIGEST_SHA_2_256:
46                 return 256;
47             case KeymasterDefs.KM_DIGEST_SHA_2_384:
48                 return 384;
49             case KeymasterDefs.KM_DIGEST_SHA_2_512:
50                 return 512;
51             default:
52                 throw new IllegalArgumentException("Unknown digest: " + keymasterDigest);
53         }
54     }
55 
56     /** @hide */
isKeymasterBlockModeIndCpaCompatibleWithSymmetricCrypto( int keymasterBlockMode)57     static boolean isKeymasterBlockModeIndCpaCompatibleWithSymmetricCrypto(
58             int keymasterBlockMode) {
59         switch (keymasterBlockMode) {
60             case KeymasterDefs.KM_MODE_ECB:
61                 return false;
62             case KeymasterDefs.KM_MODE_CBC:
63             case KeymasterDefs.KM_MODE_CTR:
64             case KeymasterDefs.KM_MODE_GCM:
65                 return true;
66             default:
67                 throw new IllegalArgumentException("Unsupported block mode: " + keymasterBlockMode);
68         }
69     }
70 
71     /** @hide */
isKeymasterPaddingSchemeIndCpaCompatibleWithAsymmetricCrypto( int keymasterPadding)72     static boolean isKeymasterPaddingSchemeIndCpaCompatibleWithAsymmetricCrypto(
73             int keymasterPadding) {
74         switch (keymasterPadding) {
75             case KeymasterDefs.KM_PAD_NONE:
76                 return false;
77             case KeymasterDefs.KM_PAD_RSA_OAEP:
78             case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
79                 return true;
80             default:
81                 throw new IllegalArgumentException(
82                         "Unsupported asymmetric encryption padding scheme: " + keymasterPadding);
83         }
84     }
85 
getEcCurveFromKeymaster(int ecCurve)86     static String getEcCurveFromKeymaster(int ecCurve) {
87         switch (ecCurve) {
88             case android.hardware.security.keymint.EcCurve.P_224:
89                 return "secp224r1";
90             case android.hardware.security.keymint.EcCurve.P_256:
91                 return "secp256r1";
92             case android.hardware.security.keymint.EcCurve.P_384:
93                 return "secp384r1";
94             case android.hardware.security.keymint.EcCurve.P_521:
95                 return "secp521r1";
96         }
97         return "";
98     }
99 
getKeymasterEcCurve(String ecCurveName)100     static int getKeymasterEcCurve(String ecCurveName) {
101         if (ecCurveName.equals("secp224r1")) {
102             return android.hardware.security.keymint.EcCurve.P_224;
103         } else if (ecCurveName.equals("secp256r1")) {
104             return android.hardware.security.keymint.EcCurve.P_256;
105         } else if (ecCurveName.equals("secp384r1")) {
106             return android.hardware.security.keymint.EcCurve.P_384;
107         } else if (ecCurveName.equals("secp521r1")) {
108             return android.hardware.security.keymint.EcCurve.P_521;
109         }
110         return -1;
111     }
112 
getCurveSpec(String name)113     static ECParameterSpec getCurveSpec(String name)
114             throws NoSuchAlgorithmException, InvalidParameterSpecException {
115         AlgorithmParameters parameters = AlgorithmParameters.getInstance("EC");
116         parameters.init(new ECGenParameterSpec(name));
117         return parameters.getParameterSpec(ECParameterSpec.class);
118     }
119 
getCurveName(ECParameterSpec spec)120     static String getCurveName(ECParameterSpec spec) {
121         if (KeymasterUtils.isECParameterSpecOfCurve(spec, "secp224r1")) {
122             return "secp224r1";
123         } else if (KeymasterUtils.isECParameterSpecOfCurve(spec, "secp256r1")) {
124             return "secp256r1";
125         } else if (KeymasterUtils.isECParameterSpecOfCurve(spec, "secp384r1")) {
126             return "secp384r1";
127         } else if (KeymasterUtils.isECParameterSpecOfCurve(spec, "secp521r1")) {
128             return "secp521r1";
129         }
130         return null;
131     }
132 
isECParameterSpecOfCurve(ECParameterSpec spec, String curveName)133     private static boolean isECParameterSpecOfCurve(ECParameterSpec spec, String curveName) {
134         try {
135             ECParameterSpec curveSpec = KeymasterUtils.getCurveSpec(curveName);
136             if (curveSpec.getCurve().equals(spec.getCurve())
137                     && curveSpec.getOrder().equals(spec.getOrder())
138                     && curveSpec.getGenerator().equals(spec.getGenerator())) {
139                 return true;
140             }
141         } catch (NoSuchAlgorithmException | InvalidParameterSpecException e) {
142             return false;
143         }
144         return false;
145     }
146 }
147