diff --git a/examples/example.py b/examples/example.py
index 00823b8..b91867f 100644
--- a/examples/example.py
+++ b/examples/example.py
@@ -63,15 +63,15 @@ def user_task(client, args):
     # ID, and the password is the secret key obtained from the IoT cloud when provisioning a device.
     client = ArduinoCloudClient(device_id=DEVICE_ID, username=DEVICE_ID, password=SECRET_KEY, sync_mode=args.sync)
 
-    # Alternatively, the client also supports key and certificate-based authentication. To use this
-    # mode, set "keyfile" and "certfile", and the CA certificate (if any) in "ssl_params".
-    # Furthermore, secure elements, which can be used to store the key and cert, are also supported.
-    # To secure elements, set "use_hsm" to True in "ssl_params" and set the token's "pin" if any.
+    # Alternatively, the client supports key and certificate-based authentication. To use this
+    # mode, set "keyfile" and "certfile", and specify the CA certificate (if any) in "ssl_params".
+    # Secure elements, which can be used to store the key and certificate, are also supported.
+    # To use secure elements, provide the key and certificate URIs (in provider:token format) and
+    # set the token's PIN (if applicable). For example:
     # client = ArduinoCloudClient(
     #     device_id=DEVICE_ID,
     #     ssl_params={
-    #         "use_hsm": True, "pin": "1234",
-    #         "keyfile": KEY_PATH, "certfile": CERT_PATH, "cafile": CA_PATH,
+    #         "pin": "1234", "keyfile": KEY_PATH, "certfile": CERT_PATH, "cafile": CA_PATH,
     #         "verify_mode": ssl.CERT_REQUIRED, "server_hostname" : "iot.arduino.cc"
     #     },
     #     sync_mode=args.sync,
diff --git a/examples/micropython_basic.py b/examples/micropython_basic.py
index b97cea8..7bfafce 100644
--- a/examples/micropython_basic.py
+++ b/examples/micropython_basic.py
@@ -18,8 +18,8 @@
 from secrets import DEVICE_ID
 from secrets import SECRET_KEY  # noqa
 
-KEY_PATH = "key.der"
-CERT_PATH = "cert.der"
+KEY_PATH = "key.der"  # noqa
+CERT_PATH = "cert.der"  # noqa
 
 
 def on_switch_changed(client, value):
@@ -76,13 +76,15 @@ def wifi_connect():
     # ID, and the password is the secret key obtained from the IoT cloud when provisioning a device.
     client = ArduinoCloudClient(device_id=DEVICE_ID, username=DEVICE_ID, password=SECRET_KEY, sync_mode=False)
 
-    # Alternatively, the client also supports key and certificate-based authentication. To use this
-    # mode, set "keyfile" and "certfile", and the CA certificate (if any) in "ssl_params".
-    # Note that for MicroPython, the key and cert files must be stored in DER format on the filesystem.
+    # Alternatively, the client supports key and certificate-based authentication. To use this
+    # mode, set "keyfile" and "certfile", and specify the CA certificate (if any) in "ssl_params".
+    # Secure elements, which can be used to store the key and certificate, are also supported.
+    # To use secure elements, provide the key and certificate URIs (in provider:token format) and
+    # set the token's PIN (if applicable). For example:
     # client = ArduinoCloudClient(
     #     device_id=DEVICE_ID,
     #     ssl_params={
-    #         "keyfile": KEY_PATH, "certfile": CERT_PATH, "cadata": CADATA,
+    #         "pin": "1234", "keyfile": KEY_PATH, "certfile": CERT_PATH, "cadata": CADATA,
     #         "verify_mode": ssl.CERT_REQUIRED, "server_hostname" : "iot.arduino.cc"
     #     },
     #     sync_mode=False,
diff --git a/src/arduino_iot_cloud/ussl.py b/src/arduino_iot_cloud/ussl.py
index f0c51af..058532a 100644
--- a/src/arduino_iot_cloud/ussl.py
+++ b/src/arduino_iot_cloud/ussl.py
@@ -9,6 +9,7 @@
 import ssl
 import sys
 import logging
+import binascii
 
 pkcs11 = None
 
@@ -16,6 +17,13 @@
 _ENGINE_PATH = "/usr/lib/engines-3/libpkcs11.so"
 _MODULE_PATH = "/usr/lib/softhsm/libsofthsm2.so"
 
+# Reference EC key for NXP's PlugNTrust
+_EC_REF_KEY = binascii.unhexlify(
+    b"3041020100301306072a8648ce3d020106082a8648ce3d03010704273025"
+    b"0201010420100000000000000000000000000000000000ffffffffa5a6b5"
+    b"b6a5a6b5b61000"
+)
+
 
 def wrap_socket(sock, ssl_params={}):
     keyfile = ssl_params.get("keyfile", None)
@@ -25,9 +33,19 @@ def wrap_socket(sock, ssl_params={}):
     ciphers = ssl_params.get("ciphers", None)
     verify = ssl_params.get("verify_mode", ssl.CERT_NONE)
     hostname = ssl_params.get("server_hostname", None)
-    use_hsm = ssl_params.get("use_hsm", False)
+    micropython = sys.implementation.name == "micropython"
+
+    if keyfile is not None and "token" in keyfile and micropython:
+        # Create a reference EC key for NXP EdgeLock device.
+        objid = int(keyfile.split("=")[1], 16).to_bytes(4, "big")
+        keyfile = _EC_REF_KEY[0:53] + objid + _EC_REF_KEY[57:]
+        # Load the certificate from the secure element (when supported).
+        # import cryptoki
+        # with cryptoki.open() as token:
+        #     cert = token.read(0x65, 412)
 
-    if not use_hsm:
+    if keyfile is None or "token" not in keyfile:
+        # Use MicroPython/CPython SSL to wrap socket.
         ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
         if hasattr(ctx, "set_default_verify_paths"):
             ctx.set_default_verify_paths()
@@ -39,7 +57,7 @@ def wrap_socket(sock, ssl_params={}):
         if ciphers is not None:
             ctx.set_ciphers(ciphers)
         if cafile is not None or cadata is not None:
-            ctx.load_verify_locations(cafile, cadata)
+            ctx.load_verify_locations(cafile=cafile, cadata=cadata)
         return ctx.wrap_socket(sock, server_hostname=hostname)
     else:
         # Use M2Crypto to load key and cert from HSM.