aboutsummaryrefslogtreecommitdiff
path: root/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMCosePairTagType.java
diff options
context:
space:
mode:
Diffstat (limited to 'ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMCosePairTagType.java')
-rw-r--r--ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMCosePairTagType.java248
1 files changed, 248 insertions, 0 deletions
diff --git a/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMCosePairTagType.java b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMCosePairTagType.java
new file mode 100644
index 0000000..baa0855
--- /dev/null
+++ b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMCosePairTagType.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright(C) 2021 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;
+
+/**
+ * This class represents the a key-value types. This is basically a map containing key value pairs.
+ * The label for the key can be (uint / int / tstr) and the value can be of any type. But this class
+ * is confined to support only key and value types which are required for remote key provisioning.
+ * So keys of type (int / uint) and values of type (int / uint / simple / bstr) only are supported.
+ * The structure representing all the sub classes of KMCosePairTagType is as follows:
+ * KM_COSE_PAIR_TAG_TYPE(1byte), Length(2 bytes), COSE_PAIR_*_TAG_TYPE(2 bytes), Key(2 bytes),
+ * Value(2 bytes). Key can be either KMInteger or KMNInteger and Value can be either KMIntger or
+ * KMNinteger or KMSimpleValue or KMByteBlob or KMTextString or KMCoseKey. Each subclass of
+ * KMCosePairTagType is named after their corresponding value type of the Cose pair.
+ */
+public abstract class KMCosePairTagType extends KMType {
+
+ /**
+ * Below table represents the allowed values for a key. The maximum length of the key can be 4
+ * bytes so each key is represented as 4 bytes. The allowed values are placed next to their
+ * corresponding key.
+ */
+ public static Object[] allowedKeyPairs;
+
+ private static void createAllowedKeyPairs() {
+ if (allowedKeyPairs == null) {
+ allowedKeyPairs =
+ new Object[] {
+ // Key type
+ (Object) new byte[] {0, 0, 0, KMCose.COSE_KEY_KEY_TYPE},
+ (Object) new byte[] {KMCose.COSE_KEY_TYPE_EC2, KMCose.COSE_KEY_TYPE_SYMMETRIC_KEY},
+ // Key Algorithm
+ (Object) new byte[] {0, 0, 0, KMCose.COSE_KEY_ALGORITHM},
+ (Object)
+ new byte[] {
+ KMCose.COSE_ALG_AES_GCM_256,
+ KMCose.COSE_ALG_HMAC_256,
+ KMCose.COSE_ALG_ECDH_ES_HKDF_256,
+ KMCose.COSE_ALG_ES256
+ },
+ // Key Curve
+ (Object) new byte[] {0, 0, 0, KMCose.COSE_KEY_CURVE},
+ (Object) new byte[] {KMCose.COSE_ECCURVE_256},
+ // Header Label Algorithm
+ (Object) new byte[] {0, 0, 0, KMCose.COSE_LABEL_ALGORITHM},
+ (Object)
+ new byte[] {
+ KMCose.COSE_ALG_AES_GCM_256,
+ KMCose.COSE_ALG_HMAC_256,
+ KMCose.COSE_ALG_ES256,
+ KMCose.COSE_ALG_ECDH_ES_HKDF_256
+ },
+ // Test Key
+ KMCose.COSE_TEST_KEY,
+ (Object) new byte[] {KMSimpleValue.NULL},
+ };
+ }
+ }
+
+ /**
+ * Validates the key and the values corresponding to key.
+ *
+ * @param key Buffer containing the key.
+ * @param keyOff Offset in the buffer from where key starts.
+ * @param keyLen Length of the key buffer.
+ * @param value Value corresponding to the key.
+ * @return true if key pair is valid, otherwise false.
+ */
+ public static boolean isKeyPairValid(byte[] key, short keyOff, short keyLen, short value) {
+ short index = 0;
+ short valueIdx;
+ byte[] values;
+ boolean valid = false;
+ createAllowedKeyPairs();
+ while (index < allowedKeyPairs.length) {
+ valueIdx = 0;
+ if (isEqual(
+ (byte[]) allowedKeyPairs[index],
+ (short) 0,
+ (short) ((byte[]) allowedKeyPairs[index]).length,
+ key,
+ keyOff,
+ keyLen)) {
+ values = (byte[]) allowedKeyPairs[(short) (index + 1)];
+ while (valueIdx < values.length) {
+ if (values[valueIdx] == (byte) value) {
+ valid = true;
+ break;
+ }
+ valueIdx++;
+ }
+ if (valid) {
+ break;
+ }
+ }
+ index += (short) 2;
+ }
+ return valid;
+ }
+
+ /**
+ * Compares two key buffers.
+ *
+ * @param key1 First buffer containing the key.
+ * @param offset1 Offset of the first buffer.
+ * @param length1 Length of the first buffer.
+ * @param key2 Second buffer containing the key.
+ * @param offset2 Offset of the second buffer.
+ * @param length2 Length of the second buffer.
+ * @return true if both keys are equal, otherwise false.
+ */
+ private static boolean isEqual(
+ byte[] key1, short offset1, short length1, byte[] key2, short offset2, short length2) {
+ if (length1 != length2) {
+ return false;
+ }
+ return (0 == KMInteger.unsignedByteArrayCompare(key1, offset1, key2, offset2, length1));
+ }
+
+ /**
+ * Returns the short value of the key.
+ *
+ * @param keyPtr Pointer to either KMInteger or KMNInteger
+ * @return value of the key as short.
+ */
+ public static short getKeyValueShort(short keyPtr) {
+ short type = KMType.getType(keyPtr);
+ short value = 0;
+ if (type == INTEGER_TYPE) {
+ value = KMInteger.cast(keyPtr).getShort();
+ } else if (type == NEG_INTEGER_TYPE) {
+ value = KMNInteger.cast(keyPtr).getShort();
+ } else {
+ ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
+ }
+ return value;
+ }
+
+ /**
+ * Returns the significant short value of the key.
+ *
+ * @param keyPtr Pointer to either KMInteger or KMNInteger
+ * @return value of the key as short.
+ */
+ public static short getKeyValueSignificantShort(short keyPtr) {
+ short type = KMType.getType(keyPtr);
+ short value = 0;
+ if (type == INTEGER_TYPE) {
+ value = KMInteger.cast(keyPtr).getSignificantShort();
+ } else if (type == NEG_INTEGER_TYPE) {
+ value = KMNInteger.cast(keyPtr).getSignificantShort();
+ } else {
+ ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
+ }
+ return value;
+ }
+
+ public static void getKeyValue(short keyPtr, byte[] dest, short offset, short len) {
+ short type = KMType.getType(keyPtr);
+ if (type == INTEGER_TYPE) {
+ KMInteger.cast(keyPtr).getValue(dest, offset, len);
+ } else if (type == NEG_INTEGER_TYPE) {
+ KMNInteger.cast(keyPtr).getValue(dest, offset, len);
+ } else {
+ ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
+ }
+ }
+
+ /**
+ * Returns the key offset from the key pointer.
+ *
+ * @param keyPtr Pointer to either KMInteger or KMNInteger
+ * @return offset from where the key starts.
+ */
+ public static short getKeyStartOffset(short keyPtr) {
+ short type = KMType.getType(keyPtr);
+ short offset = 0;
+ if (type == INTEGER_TYPE) {
+ offset = KMInteger.cast(keyPtr).getStartOff();
+ } else if (type == NEG_INTEGER_TYPE) {
+ offset = KMNInteger.cast(keyPtr).getStartOff();
+ } else {
+ ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
+ }
+ return offset;
+ }
+
+ /**
+ * Returns the key length.
+ *
+ * @param keyPtr pointer to either KMInteger/KMInteger.
+ * @return length of the key.
+ */
+ public static short getKeyLength(short keyPtr) {
+ short type = KMType.getType(keyPtr);
+ short len = 0;
+ if (type == INTEGER_TYPE) {
+ len = KMInteger.cast(keyPtr).length();
+ } else if (type == NEG_INTEGER_TYPE) {
+ len = KMNInteger.cast(keyPtr).length();
+ } else {
+ ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
+ }
+ return len;
+ }
+
+ /**
+ * This function returns one of COSE_KEY_TAG_*_VALUE_TYPE tag information.
+ *
+ * @param ptr Pointer to one of the KMCoseKey*Value class.
+ * @return Tag value type.
+ */
+ public static short getTagValueType(short ptr) {
+ return Util.getShort(heap, (short) (ptr + TLV_HEADER_SIZE));
+ }
+
+ /**
+ * This function returns the key pointer.
+ *
+ * @return key pointer.
+ */
+ public abstract short getKeyPtr();
+
+ /**
+ * This function returns the value pointer.
+ *
+ * @return value pointer.
+ */
+ public abstract short getValuePtr();
+}