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.keymaster;
18 
19 import android.compat.annotation.UnsupportedAppUsage;
20 import android.os.Build;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 
24 import java.math.BigInteger;
25 import java.util.ArrayList;
26 import java.util.Date;
27 import java.util.List;
28 
29 /**
30  * @hide
31  */
32 public class KeyCharacteristics implements Parcelable {
33     public KeymasterArguments swEnforced;
34     public KeymasterArguments hwEnforced;
35 
36     public static final @android.annotation.NonNull Parcelable.Creator<KeyCharacteristics> CREATOR =
37             new Parcelable.Creator<KeyCharacteristics>() {
38                 @Override
39                 public KeyCharacteristics createFromParcel(Parcel in) {
40                     return new KeyCharacteristics(in);
41                 }
42 
43                 @Override
44                 public KeyCharacteristics[] newArray(int length) {
45                     return new KeyCharacteristics[length];
46                 }
47             };
48 
49     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
KeyCharacteristics()50     public KeyCharacteristics() {}
51 
KeyCharacteristics(Parcel in)52     protected KeyCharacteristics(Parcel in) {
53         readFromParcel(in);
54     }
55 
56     /**
57      * Makes a shallow copy of other by copying the other's references to the KeymasterArguments
58      */
shallowCopyFrom(KeyCharacteristics other)59     public void shallowCopyFrom(KeyCharacteristics other) {
60         this.swEnforced = other.swEnforced;
61         this.hwEnforced = other.hwEnforced;
62     }
63 
64     @Override
describeContents()65     public int describeContents() {
66         return 0;
67     }
68 
69     @Override
writeToParcel(Parcel out, int flags)70     public void writeToParcel(Parcel out, int flags) {
71         swEnforced.writeToParcel(out, flags);
72         hwEnforced.writeToParcel(out, flags);
73     }
74 
75     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
readFromParcel(Parcel in)76     public void readFromParcel(Parcel in) {
77         swEnforced = KeymasterArguments.CREATOR.createFromParcel(in);
78         hwEnforced = KeymasterArguments.CREATOR.createFromParcel(in);
79     }
80 
81     /**
82      * Returns the value of the specified enum tag or {@code defaultValue} if the tag is not
83      * present.
84      *
85      * @throws IllegalArgumentException if {@code tag} is not an enum tag.
86      */
getEnum(int tag)87     public Integer getEnum(int tag) {
88         if (hwEnforced.containsTag(tag)) {
89             return hwEnforced.getEnum(tag, -1);
90         } else if (swEnforced.containsTag(tag)) {
91             return swEnforced.getEnum(tag, -1);
92         } else {
93             return null;
94         }
95     }
96 
97     /**
98      * Returns all values of the specified repeating enum tag.
99      *
100      * throws IllegalArgumentException if {@code tag} is not a repeating enum tag.
101      */
getEnums(int tag)102     public List<Integer> getEnums(int tag) {
103         List<Integer> result = new ArrayList<Integer>();
104         result.addAll(hwEnforced.getEnums(tag));
105         result.addAll(swEnforced.getEnums(tag));
106         return result;
107     }
108 
109     /**
110      * Returns the value of the specified unsigned 32-bit int tag or {@code defaultValue} if the tag
111      * is not present.
112      *
113      * @throws IllegalArgumentException if {@code tag} is not an unsigned 32-bit int tag.
114      */
getUnsignedInt(int tag, long defaultValue)115     public long getUnsignedInt(int tag, long defaultValue) {
116         if (hwEnforced.containsTag(tag)) {
117             return hwEnforced.getUnsignedInt(tag, defaultValue);
118         } else {
119             return swEnforced.getUnsignedInt(tag, defaultValue);
120         }
121     }
122 
123     /**
124      * Returns all values of the specified repeating unsigned 64-bit long tag.
125      *
126      * @throws IllegalArgumentException if {@code tag} is not a repeating unsigned 64-bit long tag.
127      */
getUnsignedLongs(int tag)128     public List<BigInteger> getUnsignedLongs(int tag) {
129         List<BigInteger> result = new ArrayList<BigInteger>();
130         result.addAll(hwEnforced.getUnsignedLongs(tag));
131         result.addAll(swEnforced.getUnsignedLongs(tag));
132         return result;
133     }
134 
135     /**
136      * Returns the value of the specified date tag or {@code null} if the tag is not present.
137      *
138      * @throws IllegalArgumentException if {@code tag} is not a date tag or if the tag's value
139      *         represents a time instant which is after {@code 2^63 - 1} milliseconds since Unix
140      *         epoch.
141      */
getDate(int tag)142     public Date getDate(int tag) {
143         Date result = swEnforced.getDate(tag, null);
144         if (result != null) {
145             return result;
146         }
147         return hwEnforced.getDate(tag, null);
148     }
149 
150     /**
151      * Returns {@code true} if the provided boolean tag is present, {@code false} if absent.
152      *
153      * @throws IllegalArgumentException if {@code tag} is not a boolean tag.
154      */
getBoolean(int tag)155     public boolean getBoolean(int tag) {
156         if (hwEnforced.containsTag(tag)) {
157             return hwEnforced.getBoolean(tag);
158         } else {
159             return swEnforced.getBoolean(tag);
160         }
161     }
162 }
163 
164