Merge "Allow re-provision of the preshared key" into main
diff --git a/apps/boot/tests/ese_operations_wrapper.cpp b/apps/boot/tests/ese_operations_wrapper.cpp
index cbf1bd5..d6f0d34 100644
--- a/apps/boot/tests/ese_operations_wrapper.cpp
+++ b/apps/boot/tests/ese_operations_wrapper.cpp
@@ -56,8 +56,7 @@
   return EseOperationsWrapperData::ops_interface->EseClose(ese);
 }
 
-EseOperationsInterface *EseOperationsWrapperData::ops_interface =
-  reinterpret_cast<EseOperationsInterface *>(NULL);
+EseOperationsInterface *EseOperationsWrapperData::ops_interface = NULL;
 
 static const char *kErrors[] = {};
 const struct EseOperations EseOperationsWrapperData::ops = {
diff --git a/libese-sysdeps/include/ese/sysdeps.h b/libese-sysdeps/include/ese/sysdeps.h
index 7d20e01..2a5f479 100644
--- a/libese-sysdeps/include/ese/sysdeps.h
+++ b/libese-sysdeps/include/ese/sysdeps.h
@@ -22,8 +22,12 @@
 #define ESE_UINT32_MAX (UINT32_MAX)
 
 #ifndef NULL
+#ifdef __cplusplus
+#define NULL nullptr
+#else
 #define NULL ((void *)(0))
 #endif
+#endif
 
 /* Set visibility for exported functions. */
 #ifndef ESE_API
diff --git a/libese-teq1/tests/ese_operations_wrapper.cpp b/libese-teq1/tests/ese_operations_wrapper.cpp
index fc3e65b..9d403d9 100644
--- a/libese-teq1/tests/ese_operations_wrapper.cpp
+++ b/libese-teq1/tests/ese_operations_wrapper.cpp
@@ -57,8 +57,7 @@
   return EseOperationsWrapperData::ops_interface->EseClose(ese);
 }
 
-EseOperationsInterface *EseOperationsWrapperData::ops_interface =
-  reinterpret_cast<EseOperationsInterface *>(NULL);
+EseOperationsInterface *EseOperationsWrapperData::ops_interface = NULL;
 
 static const char *kErrors[] = {
     TEQ1_ERROR_MESSAGES,
diff --git a/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java b/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java
index bb85b59..de74ef4 100644
--- a/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java
+++ b/ready_se/google/keymint/KM200/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java
@@ -318,11 +318,14 @@
     short len = KMEnumArrayTag.cast(tag).length();
     byte index = 0;
     while (index < len) {
-      if (KMEnumArrayTag.cast(tag).get(index) == KMType.SIGN) {
+      if (KMEnumArrayTag.cast(tag).get(index) == KMType.SIGN ||
+          KMEnumArrayTag.cast(tag).get(index) == KMType.VERIFY) {
         states[KEY_USAGE] = (byte) (states[KEY_USAGE] | keyUsageSign);
       } else if (KMEnumArrayTag.cast(tag).get(index) == KMType.WRAP_KEY) {
         states[KEY_USAGE] = (byte) (states[KEY_USAGE] | keyUsageKeyEncipher);
-      } else if (KMEnumArrayTag.cast(tag).get(index) == KMType.DECRYPT) {
+      } else if (KMEnumArrayTag.cast(tag).get(index) == KMType.DECRYPT ||
+          KMEnumArrayTag.cast(tag).get(index) == KMType.ENCRYPT) {
+        states[KEY_USAGE] = (byte) (states[KEY_USAGE] | keyUsageKeyEncipher);
         states[KEY_USAGE] = (byte) (states[KEY_USAGE] | keyUsageDataEncipher);
       } else if (KMEnumArrayTag.cast(tag).get(index) == KMType.AGREE_KEY) {
         states[KEY_USAGE] = (byte) (states[KEY_USAGE] | keyUsageKeyAgreement);
@@ -782,6 +785,7 @@
     pushByte(keyUsage);
     pushBitStringHeader(unusedBits, (short) (last - indexes[STACK_PTR]));
     pushOctetStringHeader((short) (last - indexes[STACK_PTR]));
+    pushBoolean((byte) 1); // Critical
     pushBytes(keyUsageExtn, (short) 0, (short) keyUsageExtn.length);
     pushSequenceHeader((short) (last - indexes[STACK_PTR]));
   }
diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMByteTag.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMByteTag.java
index ac49c0e..24b20b2 100644
--- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMByteTag.java
+++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMByteTag.java
@@ -75,49 +75,43 @@
 
   private static boolean validateKey(short key, short byteBlob) {
     short valueLen = KMByteBlob.cast(byteBlob).length();
+    short expectedLen = 0;
     switch (key) {
-      case ATTESTATION_APPLICATION_ID:
-        if (valueLen > MAX_ATTESTATION_APP_ID_SIZE) {
-          return false;
-        }
-        break;
-      case CERTIFICATE_SUBJECT_NAME:
-        {
-          if (valueLen > KMConfigurations.MAX_SUBJECT_DER_LEN) {
-            return false;
-          }
-          KMAsn1Parser asn1Decoder = KMAsn1Parser.instance();
-          asn1Decoder.validateDerSubject(byteBlob);
-        }
-        break;
-      case APPLICATION_ID:
-      case APPLICATION_DATA:
-        if (valueLen > MAX_APP_ID_APP_DATA_SIZE) {
-          return false;
-        }
-        break;
-      case ATTESTATION_CHALLENGE:
-        if (valueLen > MAX_ATTESTATION_CHALLENGE_SIZE) {
-          return false;
-        }
-        break;
-      case ATTESTATION_ID_BRAND:
-      case ATTESTATION_ID_DEVICE:
-      case ATTESTATION_ID_PRODUCT:
-      case ATTESTATION_ID_SERIAL:
-      case ATTESTATION_ID_IMEI:
-      case ATTESTATION_ID_MEID:
-      case ATTESTATION_ID_MANUFACTURER:
-      case ATTESTATION_ID_MODEL:
-        if (valueLen > KMConfigurations.MAX_ATTESTATION_IDS_SIZE) {
-          return false;
-        }
-        break;
-      case ROOT_OF_TRUST:
-      case NONCE:
-        break;
-      default:
-        return false;
+    case ATTESTATION_APPLICATION_ID:
+      expectedLen = MAX_ATTESTATION_APP_ID_SIZE;
+      break;
+    case CERTIFICATE_SUBJECT_NAME:
+      expectedLen = KMConfigurations.MAX_SUBJECT_DER_LEN;
+      break;
+    case APPLICATION_ID:
+    case APPLICATION_DATA:
+      expectedLen = MAX_APP_ID_APP_DATA_SIZE;
+      break;
+    case ATTESTATION_CHALLENGE:
+      expectedLen = MAX_ATTESTATION_CHALLENGE_SIZE;
+      break;
+    case ATTESTATION_ID_BRAND:
+    case ATTESTATION_ID_DEVICE:
+    case ATTESTATION_ID_PRODUCT:
+    case ATTESTATION_ID_SERIAL:
+    case ATTESTATION_ID_IMEI:
+    case ATTESTATION_ID_SECOND_IMEI:
+    case ATTESTATION_ID_MEID:
+    case ATTESTATION_ID_MANUFACTURER:
+    case ATTESTATION_ID_MODEL:
+      expectedLen = KMConfigurations.MAX_ATTESTATION_IDS_SIZE;
+      break;
+    case NONCE:
+      // Nonce validation occurs during the begin operation, as its validation relies
+      // on other TAGs.
+      return true;
+    default:
+      return false;
+    }
+    KMTag.assertLE(valueLen, expectedLen, KMError.INVALID_INPUT_LENGTH);
+    if (key == CERTIFICATE_SUBJECT_NAME) {
+      KMAsn1Parser asn1Decoder = KMAsn1Parser.instance();
+      asn1Decoder.validateDerSubject(byteBlob);
     }
     return true;
   }
diff --git a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMTag.java b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMTag.java
index d7d549a..f96e18d 100644
--- a/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMTag.java
+++ b/ready_se/google/keymint/KM200/Applet/src/com/android/javacard/keymaster/KMTag.java
@@ -38,6 +38,12 @@
     return Util.getShort(heap, (short) (ptr + TLV_HEADER_SIZE + 2));
   }
 
+  public static void assertLE(short val1, short val2, short error) {
+    if (val1 > val2) {
+      KMException.throwIt(error);
+    }
+  }
+
   public static void assertPresence(short params, short tagType, short tagKey, short error) {
     if (!isPresent(params, tagType, tagKey)) {
       KMException.throwIt(error);
diff --git a/ready_se/google/keymint/KM200/HAL/Android.bp b/ready_se/google/keymint/KM200/HAL/Android.bp
index b05bb3e..11a32f9 100644
--- a/ready_se/google/keymint/KM200/HAL/Android.bp
+++ b/ready_se/google/keymint/KM200/HAL/Android.bp
@@ -54,7 +54,7 @@
         "android.hardware.security.rkp-V3-ndk",
         "lib_android_keymaster_keymint_utils",
         "libbase",
-        "libcppbor_external",
+        "libcppbor",
         "libkeymaster_portable",
         "libkeymaster_messages",
         "libsoft_attestation_cert",
@@ -115,7 +115,7 @@
         "android.hardware.security.rkp-V3-ndk",
         "libbase",
         "libbinder_ndk",
-        "libcppbor_external",
+        "libcppbor",
         "libcrypto",
         "libkeymaster_portable",
         "libjc_keymint",
diff --git a/ready_se/google/keymint/KM300/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java b/ready_se/google/keymint/KM300/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java
index 9cc3777..5c045f8 100644
--- a/ready_se/google/keymint/KM300/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java
+++ b/ready_se/google/keymint/KM300/Applet/AndroidSEProvider/src/com/android/javacard/keymaster/KMAttestationCertImpl.java
@@ -319,11 +319,14 @@
     short len = KMEnumArrayTag.cast(tag).length();
     byte index = 0;
     while (index < len) {
-      if (KMEnumArrayTag.cast(tag).get(index) == KMType.SIGN) {
+      if (KMEnumArrayTag.cast(tag).get(index) == KMType.SIGN ||
+          KMEnumArrayTag.cast(tag).get(index) == KMType.VERIFY) {
         states[KEY_USAGE] = (byte) (states[KEY_USAGE] | keyUsageSign);
       } else if (KMEnumArrayTag.cast(tag).get(index) == KMType.WRAP_KEY) {
         states[KEY_USAGE] = (byte) (states[KEY_USAGE] | keyUsageKeyEncipher);
-      } else if (KMEnumArrayTag.cast(tag).get(index) == KMType.DECRYPT) {
+      } else if (KMEnumArrayTag.cast(tag).get(index) == KMType.DECRYPT ||
+          KMEnumArrayTag.cast(tag).get(index) == KMType.ENCRYPT) {
+        states[KEY_USAGE] = (byte) (states[KEY_USAGE] | keyUsageKeyEncipher);
         states[KEY_USAGE] = (byte) (states[KEY_USAGE] | keyUsageDataEncipher);
       } else if (KMEnumArrayTag.cast(tag).get(index) == KMType.AGREE_KEY) {
         states[KEY_USAGE] = (byte) (states[KEY_USAGE] | keyUsageKeyAgreement);
@@ -783,6 +786,7 @@
     pushByte(keyUsage);
     pushBitStringHeader(unusedBits, (short) (last - indexes[STACK_PTR]));
     pushOctetStringHeader((short) (last - indexes[STACK_PTR]));
+    pushBoolean((byte) 1); // Critical
     pushBytes(keyUsageExtn, (short) 0, (short) keyUsageExtn.length);
     pushSequenceHeader((short) (last - indexes[STACK_PTR]));
   }
diff --git a/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMByteTag.java b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMByteTag.java
index 5f7231f..24b20b2 100644
--- a/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMByteTag.java
+++ b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMByteTag.java
@@ -75,50 +75,43 @@
 
   private static boolean validateKey(short key, short byteBlob) {
     short valueLen = KMByteBlob.cast(byteBlob).length();
+    short expectedLen = 0;
     switch (key) {
-      case ATTESTATION_APPLICATION_ID:
-        if (valueLen > MAX_ATTESTATION_APP_ID_SIZE) {
-          return false;
-        }
-        break;
-      case CERTIFICATE_SUBJECT_NAME:
-        {
-          if (valueLen > KMConfigurations.MAX_SUBJECT_DER_LEN) {
-            return false;
-          }
-          KMAsn1Parser asn1Decoder = KMAsn1Parser.instance();
-          asn1Decoder.validateDerSubject(byteBlob);
-        }
-        break;
-      case APPLICATION_ID:
-      case APPLICATION_DATA:
-        if (valueLen > MAX_APP_ID_APP_DATA_SIZE) {
-          return false;
-        }
-        break;
-      case ATTESTATION_CHALLENGE:
-        if (valueLen > MAX_ATTESTATION_CHALLENGE_SIZE) {
-          return false;
-        }
-        break;
-      case ATTESTATION_ID_BRAND:
-      case ATTESTATION_ID_DEVICE:
-      case ATTESTATION_ID_PRODUCT:
-      case ATTESTATION_ID_SERIAL:
-      case ATTESTATION_ID_IMEI:
-      case ATTESTATION_ID_SECOND_IMEI:
-      case ATTESTATION_ID_MEID:
-      case ATTESTATION_ID_MANUFACTURER:
-      case ATTESTATION_ID_MODEL:
-        if (valueLen > KMConfigurations.MAX_ATTESTATION_IDS_SIZE) {
-          return false;
-        }
-        break;
-      case ROOT_OF_TRUST:
-      case NONCE:
-        break;
-      default:
-        return false;
+    case ATTESTATION_APPLICATION_ID:
+      expectedLen = MAX_ATTESTATION_APP_ID_SIZE;
+      break;
+    case CERTIFICATE_SUBJECT_NAME:
+      expectedLen = KMConfigurations.MAX_SUBJECT_DER_LEN;
+      break;
+    case APPLICATION_ID:
+    case APPLICATION_DATA:
+      expectedLen = MAX_APP_ID_APP_DATA_SIZE;
+      break;
+    case ATTESTATION_CHALLENGE:
+      expectedLen = MAX_ATTESTATION_CHALLENGE_SIZE;
+      break;
+    case ATTESTATION_ID_BRAND:
+    case ATTESTATION_ID_DEVICE:
+    case ATTESTATION_ID_PRODUCT:
+    case ATTESTATION_ID_SERIAL:
+    case ATTESTATION_ID_IMEI:
+    case ATTESTATION_ID_SECOND_IMEI:
+    case ATTESTATION_ID_MEID:
+    case ATTESTATION_ID_MANUFACTURER:
+    case ATTESTATION_ID_MODEL:
+      expectedLen = KMConfigurations.MAX_ATTESTATION_IDS_SIZE;
+      break;
+    case NONCE:
+      // Nonce validation occurs during the begin operation, as its validation relies
+      // on other TAGs.
+      return true;
+    default:
+      return false;
+    }
+    KMTag.assertLE(valueLen, expectedLen, KMError.INVALID_INPUT_LENGTH);
+    if (key == CERTIFICATE_SUBJECT_NAME) {
+      KMAsn1Parser asn1Decoder = KMAsn1Parser.instance();
+      asn1Decoder.validateDerSubject(byteBlob);
     }
     return true;
   }
diff --git a/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java
index abbc860..e122283 100644
--- a/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java
+++ b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java
@@ -4070,17 +4070,6 @@
 
     data[CERTIFICATE] = KMArray.instance((short) 0); // by default the cert is empty.
     data[ORIGIN] = KMType.IMPORTED;
-    // ID_IMEI should be present if ID_SECOND_IMEI is present
-    short attIdTag =
-        KMKeyParameters.findTag(
-            KMType.BYTES_TAG, KMType.ATTESTATION_ID_SECOND_IMEI, data[KEY_PARAMETERS]);
-    if (attIdTag != KMType.INVALID_VALUE) {
-      KMTag.assertPresence(
-          data[KEY_PARAMETERS],
-          KMType.BYTES_TAG,
-          KMType.ATTESTATION_ID_IMEI,
-          KMError.CANNOT_ATTEST_IDS);
-    }
     importKey(apdu, keyFmt, scratchPad);
   }
 
@@ -4548,17 +4537,6 @@
       KMException.throwIt(KMError.UNSUPPORTED_TAG);
     }
 
-    // ID_IMEI should be present if ID_SECOND_IMEI is present
-    short attIdTag =
-        KMKeyParameters.findTag(
-            KMType.BYTES_TAG, KMType.ATTESTATION_ID_SECOND_IMEI, data[KEY_PARAMETERS]);
-    if (attIdTag != KMType.INVALID_VALUE) {
-      KMTag.assertPresence(
-          data[KEY_PARAMETERS],
-          KMType.BYTES_TAG,
-          KMType.ATTESTATION_ID_IMEI,
-          KMError.CANNOT_ATTEST_IDS);
-    }
 
     short attKeyPurpose =
         KMKeyParameters.findTag(KMType.ENUM_ARRAY_TAG, KMType.PURPOSE, data[KEY_PARAMETERS]);
diff --git a/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMTag.java b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMTag.java
index d7d549a..f96e18d 100644
--- a/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMTag.java
+++ b/ready_se/google/keymint/KM300/Applet/src/com/android/javacard/keymaster/KMTag.java
@@ -38,6 +38,12 @@
     return Util.getShort(heap, (short) (ptr + TLV_HEADER_SIZE + 2));
   }
 
+  public static void assertLE(short val1, short val2, short error) {
+    if (val1 > val2) {
+      KMException.throwIt(error);
+    }
+  }
+
   public static void assertPresence(short params, short tagType, short tagKey, short error) {
     if (!isPresent(params, tagType, tagKey)) {
       KMException.throwIt(error);
diff --git a/ready_se/google/keymint/KM300/HAL/Android.bp b/ready_se/google/keymint/KM300/HAL/Android.bp
index fd38d10..732ad1b 100644
--- a/ready_se/google/keymint/KM300/HAL/Android.bp
+++ b/ready_se/google/keymint/KM300/HAL/Android.bp
@@ -54,7 +54,7 @@
         "android.hardware.security.rkp-V3-ndk",
         "lib_android_keymaster_keymint_utils",
         "libbase",
-        "libcppbor_external",
+        "libcppbor",
         "libkeymaster_portable",
         "libkeymaster_messages",
         "libsoft_attestation_cert",
@@ -92,7 +92,7 @@
         "android.hardware.security.rkp-V3-ndk",
         "libbase",
         "libbinder_ndk",
-        "libcppbor_external",
+        "libcppbor",
         "libcrypto",
         "libkeymaster_portable",
         "libjc_keymint3",