Skip to main content

Simple Actions

Some Information​

The basic actions in Tesla vehicles are called RKE actions - Remote Keyless Entry Actions in other word. They can do some simple things like opening the trunk or frunk, or even locking and unlocking the vehicle.

Structure​

RKE Actions are regular old UnsignedMessage messages, signed and sent off to the vehicle.

Here's an example of an unlock message:

UnsignedMessage {
RKEAction: RKE_ACTION_UNLOCK
}
Python Example
import VCSEC
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import hashes, serialization

# Function to prepend message length
def prependLength(message):
return (len(message).to_bytes(2, 'big') + message)

try:
# Try to open and import private key
privKeyFile = open('private_key.pem', 'rb')
privateKey = serialization.load_pem_private_key(privKeyFile.read(), None)
privKeyFile.close()
except FileNotFoundError:
# If private key file not found, generate private keys
privKeyFile = open('private_key.pem', 'wb')
privateKey = ec.generate_private_key(ec.SECP256R1())
privKeyFile.write(privateKey.private_bytes(serialization.Encoding.PEM, serialization.PrivateFormat.PKCS8, serialization.NoEncryption()))
privKeyFile.close()

# Derive public key in X9.62 Uncompressed Point Encoding
publicKey = privateKey.public_key().public_bytes(serialization.Encoding.X962, serialization.PublicFormat.UncompressedPoint)

# Hash our public key to get our key id and extract the first 4 bytes
digest = hashes.Hash(hashes.SHA1())
digest.update(publicKey)
keyId = digest.finalize()[:4]

# Example Ephemeral Key
ephemeralKey = b'\x04\x79\xc0\x50\x4a\x21\x6f\xfc\x26\x46\xb7\x57\x80\x39\x9f\x1c\xe1\x23\xf4\x01\x56\x1b\x68\x5c\x31\x83\x64\xfa\x96\xcc\x3f\xe6\x7a\x5a\xc5\x04\x8c\x44\x7a\xf8\x8d\x91\x52\x86\x5a\x1e\xfc\x15\xbb\xd5\x68\x98\xdd\x2c\x46\xf7\xa1\x9b\xad\x4f\xb2\x80\x52\xc4\x60'

# Put the known curve of the key into a variable
curve = ec.SECP256R1()
# Use the curve to put the ephemeral key into a workable format
ephemeralKey = ec.EllipticCurvePublicKey.from_encoded_point(curve, ephemeralKey)
# Prepare a hasher
hasher = hashes.Hash(hashes.SHA1())
# Derive an AES secret from our private key and the vehicle's public key
aesSecret = privateKey.exchange(ec.ECDH(), ephemeralKey)
# Put the AES secret into the hasher
hasher.update(aesSecret)
# Put the first 16 bytes of the hash into a shared key variable
sharedKey = hasher.finalize()[:16]

# Put an rke action on an unsigned message with an unlock action and serialize it
unsignedMessage = VCSEC.UnsignedMessage()
unsignedMessage.RKEAction = VCSEC.RKEAction_E.RKE_ACTION_UNLOCK
unsignedMessageS = unsignedMessage.SerializeToString()

# Print out the unsigned message layout for information purposes
print("Unsigned Message Layout:")
print(unsignedMessage)

# Set counter to 3 and create a nonce from it
counter = 3
nonce = int.to_bytes(counter, 4, "big")

# Initialize an AES encryptor in GCM mode and encrypt the message using it
encryptor = AESGCM(sharedKey)
# This will error out if you're using the latest version of the cryptorgraphy.io library as I'm using a 4 byte long nonce
try:
encryptedMsgWithTag = encryptor.encrypt(nonce, unsignedMessageS, None)
except ValueError:
print("Error: The cryptography.io library doesn't allow nonces as small as 4 bytes anymore. Please modify the if statement in the _check_params(nonce, data, associated_date) function in the cryptography.hazmat.primitives.ciphers.aead.AESGCM class to require the minimum length to be 1")
exit()

# Put all of this onto a "signed message" variable
signedMessage = VCSEC.SignedMessage()
signedMessage.protobufMessageAsBytes = encryptedMsgWithTag[:-16]
signedMessage.counter = counter
signedMessage.signature = encryptedMsgWithTag[-16:]
signedMessage.keyId = keyId

# Put all of this onto a "to vcsec" message
toVCSECMessage = VCSEC.ToVCSECMessage()
toVCSECMessage.signedMessage.CopyFrom(signedMessage)

# Print it out for information purposes
print("\nTo VCSEC Message Layout:")
print(toVCSECMessage)

# Serialize the message and prepend the length
msg = toVCSECMessage.SerializeToString()
msg = prependLength(msg)

# Print the message to be sent to the vehicle
print("\nRKE Action Message To Send To Vehicle:")
print(msg.hex(" "))

Other Actions​

As you can see, these are pretty easy to make, here's a table describing what every other action does:

ActionDescription
RKE_ACTION_UNLOCKUnlocks the vehicle
RKE_ACTION_LOCKLocks the vehicle
RKE_ACTION_OPEN_TRUNKOpens the trunk
RKE_ACTION_OPEN_FRUNKOpens the frunk
RKE_ACTION_OPEN_CHARGE_PORTOpens the charging port
RKE_ACTION_CLOSE_CHARGE_PORTCloses the charging port
RKE_ACTION_CANCEL_EXTERNAL_AUTHENTICATE...
RKE_ACTION_SINGLE_PRESS_TOPKeyfob Action - Single press top of keyfob
RKE_ACTION_DOUBLE_PRESS_TOPKeyfob Action - Double press top of keyfob
RKE_ACTION_TRIPLE_PRESS_TOPKeyfob Action - Triple press top of keyfob
RKE_ACTION_HOLD_TOPKeyfob Action - Hold top of keyfob
RKE_ACTION_SINGLE_PRESS_BACKKeyfob Action - Single press back of keyfob
RKE_ACTION_DOUBLE_PRESS_BACKKeyfob Action - Double press back of keyfob
RKE_ACTION_TRIPLE_PRESS_BACKKeyfob Action - Triple press back of keyfob
RKE_ACTION_HOLD_BACKKeyfob Action - Hold back of keyfob
RKE_ACTION_SINGLE_PRESS_FRONTKeyfob Action - Single press front of keyfob
RKE_ACTION_DOUBLE_PRESS_FRONTKeyfob Action - Double press front of keyfob
RKE_ACTION_TRIPLE_PRESS_FRONTKeyfob Action - Triple press front of keyfob
RKE_ACTION_HOLD_FRONTKeyfob Action - Hold front of keyfob
RKE_ACTION_UNKNOWN...
RKE_ACTION_REMOTE_DRIVE
  • Pre 2022.16.1.2: Open a 2 minute period within which the vehicle can be started without Pin To Drive
  • 2022.16.1.2 and later: useless action, does nothing
RKE_ACTION_SINGLE_PRESS_LEFTKeyfob Action - Single press left of keyfob
RKE_ACTION_DOUBLE_PRESS_LEFTKeyfob Action - Double press left of keyfob
RKE_ACTION_TRIPLE_PRESS_LEFTKeyfob Action - Triple press left of keyfob
RKE_ACTION_HOLD_LEFTKeyfob Action - Hold left of keyfob
RKE_ACTION_SINGLE_PRESS_RIGHTKeyfob Action - Single press right of keyfob
RKE_ACTION_DOUBLE_PRESS_RIGHTKeyfob Action - Double press right of keyfob
RKE_ACTION_TRIPLE_PRESS_RIGHTKeyfob Action - Triple press right of keyfob
RKE_ACTION_HOLD_RIGHTKeyfob Action - Hold right of keyfob
RKE_ACTION_AUTO_SECURE_VEHICLEManually trigger walkaway lock (better than just sending lock command, as it lets the windows roll up if that option is enabled)
RKE_ACTION_WAKE_VEHICLEWake up the vehicle