aboutsummaryrefslogtreecommitdiff
path: root/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMCoseMap.java
diff options
context:
space:
mode:
Diffstat (limited to 'ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMCoseMap.java')
-rw-r--r--ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMCoseMap.java171
1 files changed, 171 insertions, 0 deletions
diff --git a/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMCoseMap.java b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMCoseMap.java
new file mode 100644
index 0000000..5d373a7
--- /dev/null
+++ b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMCoseMap.java
@@ -0,0 +1,171 @@
+/*
+ * 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" (short)0IS,
+ * 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.JCSystem;
+import javacard.framework.Util;
+
+/**
+ * This class represents either a Cose_key or Cose headers as defined in
+ * https://datatracker.ietf.org/doc/html/rfc8152 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.
+ * KMCoseHeaders and KMCoseKey implements this class.
+ */
+public abstract class KMCoseMap extends KMType {
+
+ public static byte[] scratchpad;
+
+ /**
+ * This function creates an instance of either KMCoseHeaders or KMCoseKey based on the type
+ * information provided.
+ *
+ * @param typePtr type information of the underlying KMType.
+ * @param arrPtr instance of KMArray.
+ * @return instance type of either KMCoseHeaders or KMCoseKey.
+ */
+ public static short createInstanceFromType(short typePtr, short arrPtr) {
+ short mapType = KMType.getType(typePtr);
+ switch (mapType) {
+ case KMType.COSE_HEADERS_TYPE:
+ return KMCoseHeaders.instance(arrPtr);
+ case KMType.COSE_KEY_TYPE:
+ return KMCoseKey.instance(arrPtr);
+ case KMType.COSE_CERT_PAYLOAD_TYPE:
+ return KMCoseCertPayload.instance(arrPtr);
+ default:
+ ISOException.throwIt(ISO7816.SW_DATA_INVALID);
+ return 0;
+ }
+ }
+
+ public static short getVals(short ptr) {
+ short mapType = KMType.getType(ptr);
+ switch (mapType) {
+ case KMType.COSE_HEADERS_TYPE:
+ return KMCoseHeaders.cast(ptr).getVals();
+ case KMType.COSE_KEY_TYPE:
+ return KMCoseKey.cast(ptr).getVals();
+ case KMType.COSE_CERT_PAYLOAD_TYPE:
+ return KMCoseCertPayload.cast(ptr).getVals();
+ default:
+ ISOException.throwIt(ISO7816.SW_DATA_INVALID);
+ return 0;
+ }
+ }
+
+ private static short getKey(short tagPtr) {
+ short tagType = KMCosePairTagType.getTagValueType(tagPtr);
+ switch (tagType) {
+ case KMType.COSE_PAIR_BYTE_BLOB_TAG_TYPE:
+ return KMCosePairByteBlobTag.cast(tagPtr).getKeyPtr();
+ case KMType.COSE_PAIR_INT_TAG_TYPE:
+ return KMCosePairIntegerTag.cast(tagPtr).getKeyPtr();
+ case KMType.COSE_PAIR_NEG_INT_TAG_TYPE:
+ return KMCosePairNegIntegerTag.cast(tagPtr).getKeyPtr();
+ case KMType.COSE_PAIR_SIMPLE_VALUE_TAG_TYPE:
+ return KMCosePairSimpleValueTag.cast(tagPtr).getKeyPtr();
+ case KMType.COSE_PAIR_COSE_KEY_TAG_TYPE:
+ return KMCosePairCoseKeyTag.cast(tagPtr).getKeyPtr();
+ case KMType.COSE_PAIR_TEXT_STR_TAG_TYPE:
+ return KMCosePairTextStringTag.cast(tagPtr).getKeyPtr();
+ default:
+ ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
+ }
+ return 0;
+ }
+
+ private static void createScratchBuffer() {
+ if (scratchpad == null) {
+ scratchpad = JCSystem.makeTransientByteArray((short) 120, JCSystem.CLEAR_ON_RESET);
+ }
+ }
+
+ protected static void canonicalize(short arr) {
+ canonicalize(arr, KMArray.cast(arr).length());
+ }
+
+ private static void swap(short ptr, short firstIndex, short secondIndex) {
+ if (KMType.getType(ptr) == KMType.ARRAY_TYPE) {
+ KMArray.cast(ptr).swap(firstIndex, secondIndex);
+ } else {
+ KMMap.cast(ptr).swap(firstIndex, secondIndex);
+ }
+ }
+
+ private static boolean compareAndSwap(short ptr, short index) {
+ short firstKey;
+ short secondKey;
+ short firstKeyLen;
+ short secondKeyLen;
+ if (KMType.getType(ptr) == KMType.ARRAY_TYPE) {
+ firstKey = getKey(KMArray.cast(ptr).get(index));
+ secondKey = getKey(KMArray.cast(ptr).get((short) (index + 1)));
+ } else { // Map
+ firstKey = KMMap.cast(ptr).getKey(index);
+ secondKey = KMMap.cast(ptr).getKey((short) (index + 1));
+ }
+ firstKeyLen =
+ KMKeymasterApplet.encoder.encode(
+ firstKey, scratchpad, (short) 0, (short) scratchpad.length);
+ secondKeyLen =
+ KMKeymasterApplet.encoder.encode(
+ secondKey, scratchpad, firstKeyLen, (short) scratchpad.length);
+ if ((firstKeyLen > secondKeyLen)
+ || ((firstKeyLen == secondKeyLen)
+ && (0
+ < Util.arrayCompare(
+ scratchpad, (short) 0, scratchpad, firstKeyLen, firstKeyLen)))) {
+ swap(ptr, index, (short) (index + 1));
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Canonicalizes using bubble sort.
+ *
+ * @param ptr instance pointer of either array or map.
+ * @param length length of the array or map instance.
+ */
+ public static void canonicalize(short ptr, short length) {
+ short index = 0;
+ short innerIndex = 0;
+ createScratchBuffer();
+ boolean swapped;
+ while (index < length) {
+ swapped = false;
+ innerIndex = 0;
+ while (innerIndex < (short) (length - index - 1)) {
+ swapped |= compareAndSwap(ptr, innerIndex);
+ innerIndex++;
+ }
+ if (!swapped) {
+ break;
+ }
+ index++;
+ }
+ }
+
+ public abstract short getVals();
+
+ public abstract short length();
+
+ public abstract void canonicalize();
+}