aboutsummaryrefslogtreecommitdiff
path: root/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEnum.java
diff options
context:
space:
mode:
Diffstat (limited to 'ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEnum.java')
-rw-r--r--ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEnum.java166
1 files changed, 166 insertions, 0 deletions
diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEnum.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEnum.java
new file mode 100644
index 0000000..44bf477
--- /dev/null
+++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMEnum.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright(C) 2020 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 com.android.javacard.keymaster;
+
+import javacard.framework.ISO7816;
+import javacard.framework.ISOException;
+import javacard.framework.Util;
+
+/**
+ * KMEnum represents an enumeration specified in android keymaster hal specifications. It
+ * corresponds to uint CBOR type and it is a byte value. struct{byte ENUM_TYPE; short length;
+ * struct{short enumType; byte val}}
+ */
+public class KMEnum extends KMType {
+
+ private static KMEnum prototype;
+
+ // The allowed enum types.
+ private static short[] types = {
+ HARDWARE_TYPE,
+ KEY_FORMAT,
+ KEY_DERIVATION_FUNCTION,
+ VERIFIED_BOOT_STATE,
+ DEVICE_LOCKED,
+ USER_AUTH_TYPE,
+ PURPOSE,
+ ECCURVE,
+ RULE
+ };
+
+ private static Object[] enums = null;
+
+ private KMEnum() {}
+
+ private static KMEnum proto(short ptr) {
+ if (prototype == null) {
+ prototype = new KMEnum();
+ }
+ KMType.instanceTable[KM_ENUM_OFFSET] = ptr;
+ return prototype;
+ }
+
+ // pointer to an empty instance used as expression
+ public static short exp() {
+ return KMType.exp(ENUM_TYPE);
+ }
+
+ public static KMEnum cast(short ptr) {
+ if (heap[ptr] != ENUM_TYPE) {
+ ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
+ }
+ if (Util.getShort(heap, (short) (ptr + 1)) == INVALID_VALUE) {
+ ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
+ }
+ return proto(ptr);
+ }
+
+ public static short instance(short enumType) {
+ if (!validateEnum(enumType, NO_VALUE)) {
+ ISOException.throwIt(ISO7816.SW_DATA_INVALID);
+ }
+ short ptr = KMType.instance(ENUM_TYPE, (short) 2);
+ Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), enumType);
+ return ptr;
+ }
+
+ public static short instance(short enumType, byte val) {
+ if (!validateEnum(enumType, val)) {
+ ISOException.throwIt(ISO7816.SW_DATA_INVALID);
+ }
+ short ptr = KMType.instance(ENUM_TYPE, (short) 3);
+ Util.setShort(heap, (short) (ptr + TLV_HEADER_SIZE), enumType);
+ heap[(short) (ptr + TLV_HEADER_SIZE + 2)] = val;
+ return ptr;
+ }
+
+ private static void create() {
+ // The allowed enum values to corresponding enum types in the types array.
+ if (enums == null) {
+ enums =
+ new Object[] {
+ new byte[] {SOFTWARE, TRUSTED_ENVIRONMENT, STRONGBOX},
+ new byte[] {X509, PKCS8, RAW},
+ new byte[] {
+ DERIVATION_NONE,
+ RFC5869_SHA256,
+ ISO18033_2_KDF1_SHA1,
+ ISO18033_2_KDF1_SHA256,
+ ISO18033_2_KDF2_SHA1,
+ ISO18033_2_KDF2_SHA256
+ },
+ new byte[] {SELF_SIGNED_BOOT, VERIFIED_BOOT, UNVERIFIED_BOOT, FAILED_BOOT},
+ new byte[] {DEVICE_LOCKED_TRUE, DEVICE_LOCKED_FALSE},
+ new byte[] {USER_AUTH_NONE, PASSWORD, FINGERPRINT, BOTH},
+ new byte[] {ENCRYPT, DECRYPT, SIGN, VERIFY, WRAP_KEY, ATTEST_KEY, AGREE_KEY},
+ new byte[] {P_224, P_256, P_384, P_521},
+ new byte[] {IGNORE_INVALID_TAGS, FAIL_ON_INVALID_TAGS}
+ };
+ }
+ }
+
+ // isValidTag enumeration keys and values.
+ private static boolean validateEnum(short key, byte value) {
+ create();
+ byte[] vals;
+ short enumInd;
+ // check if key exists
+ short index = (short) types.length;
+ while (--index >= 0) {
+ if (types[index] == key) {
+ // check if value given
+ if (value != NO_VALUE) {
+ // check if the value exist
+ vals = (byte[]) enums[index];
+ enumInd = (short) vals.length;
+ while (--enumInd >= 0) {
+ if (vals[enumInd] == value) {
+ // return true if value exist
+ return true;
+ }
+ }
+ // return false if value does not exist
+ return false;
+ }
+ // return true if key exist and value not given
+ return true;
+ }
+ }
+ // return false if key does not exist
+ return false;
+ }
+
+ public short length() {
+ return Util.getShort(heap, (short) (KMType.instanceTable[KM_ENUM_OFFSET] + 1));
+ }
+
+ public byte getVal() {
+ return heap[(short) (KMType.instanceTable[KM_ENUM_OFFSET] + TLV_HEADER_SIZE + 2)];
+ }
+
+ public void setVal(byte val) {
+ heap[(short) (KMType.instanceTable[KM_ENUM_OFFSET] + TLV_HEADER_SIZE + 2)] = val;
+ }
+
+ public short getEnumType() {
+ return Util.getShort(heap, (short) (KMType.instanceTable[KM_ENUM_OFFSET] + TLV_HEADER_SIZE));
+ }
+
+ public void setEnumType(short type) {
+ Util.setShort(heap, (short) (KMType.instanceTable[KM_ENUM_OFFSET] + TLV_HEADER_SIZE), type);
+ }
+}