Skip to content

Commit

Permalink
Merge pull request #7 from yoziru/fix-set-is-authenticated
Browse files Browse the repository at this point in the history
fix set is authenticated
  • Loading branch information
yoziru authored Jul 28, 2024
2 parents 0c1685b + 345bc00 commit 4969c1a
Show file tree
Hide file tree
Showing 12 changed files with 814 additions and 758 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.22)

include(FetchContent)
project(TeslaBLE
VERSION 2.1.1
VERSION 2.2.0
DESCRIPTION "CPP Tesla BLE Library"
LANGUAGES CXX C
)
Expand Down
2 changes: 1 addition & 1 deletion examples/simple/log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ static const char *domain_to_string(UniversalMessage_Domain domain)
}

static void log_destination(const char *direction,
const UniversalMessage_Destination *dest)
const UniversalMessage_Destination *dest)
{
printf("Destination: %s\n", direction);
printf(" which_sub_destination: %d\n", dest->which_sub_destination);
Expand Down
217 changes: 89 additions & 128 deletions examples/simple/main.cpp

Large diffs are not rendered by default.

322 changes: 169 additions & 153 deletions include/client.h
Original file line number Diff line number Diff line change
@@ -1,36 +1,15 @@
#ifndef TESLA_BLE_CLIENT_H
#define TESLA_BLE_CLIENT_H
// https://github.com/platformio/platform-espressif32/issues/957
// specifically set when compiling with ESP-IDF
#ifdef ESP_PLATFORM
#define MBEDTLS_CONFIG_FILE "mbedtls/esp_config.h"
#endif

#ifdef ESP_PLATFORM
#include "esp_log.h"
#define LOG_ERROR(...) ESP_LOGE("TeslaBLE", __VA_ARGS__)
#else
#include <cstdio>
#include <cstdarg>

inline void LOG_ERROR(const char* format, ...)
{
va_list args;
va_start(args, format);
printf("\033[1;31m[E] ");
vprintf(format, args);
printf("\033[0m\n");
va_end(args);
}
#endif
#pragma once

#include <string>
#include <memory> // Add this for std::shared_ptr

#include "mbedtls/ctr_drbg.h"
#include "mbedtls/ecdh.h"
#include "mbedtls/pk.h"
#include "mbedtls/sha1.h"
#include <chrono>

#include "defs.h"
#include "peer.h"
#include "car_server.pb.h"
#include "universal_message.pb.h"
Expand All @@ -41,153 +20,190 @@ namespace TeslaBLE
{
class Client
{
static const int SHARED_KEY_SIZE_BYTES = 16;

private:
mbedtls_pk_context private_key_context_;
mbedtls_ecp_keypair tesla_key_vcsec_;
mbedtls_ecp_keypair tesla_key_infotainment_;
mbedtls_ecdh_context ecdh_context_;
mbedtls_ctr_drbg_context drbg_context_;
pb_byte_t shared_secret_infotainment_sha1_[SHARED_KEY_SIZE_BYTES];
pb_byte_t shared_secret_vcsec_sha1_[SHARED_KEY_SIZE_BYTES];
unsigned char key_id_[4];
unsigned char public_key_[MBEDTLS_ECP_MAX_BYTES];
size_t public_key_size_;

// pb_byte_t epoch_[16];
pb_byte_t nonce_[12];
// uint32_t counter_ = 1;
// uint32_t expires_at_ = 0;
pb_byte_t connectionID[16] = {0x0A, 0x79, 0x62, 0xc1, 0x0d, 0x38, 0xb6, 0x1d, 0xd2, 0xa7, 0x72, 0x27, 0x80, 0xa4, 0xf0, 0x96};
const char *VIN = "";

static void prependLength(const pb_byte_t *input_buffer,
size_t input_buffer_length,
pb_byte_t *output_buffer,
size_t *output_buffer_length);

int generatePublicKey();

int GenerateKeyId();

int ConstructADBuffer(Signatures_SignatureType signature_type,
UniversalMessage_Domain domain,
const char *VIN,
pb_byte_t *epoch,
uint32_t expires_at,
uint32_t counter,
pb_byte_t *output_buffer,
size_t *output_length);

int Encrypt(pb_byte_t *input_buffer, size_t input_buffer_length,
pb_byte_t *output_buffer, size_t output_buffer_length,
size_t *output_length, pb_byte_t *signature_buffer,
pb_byte_t *ad_buffer, size_t ad_buffer_length,
UniversalMessage_Domain domain);

public:
Peer session_vcsec_;
Peer session_infotainment_;
Client()
: private_key_context_(std::make_unique<mbedtls_pk_context>()),
ecdh_context_(std::make_unique<mbedtls_ecdh_context>()),
drbg_context_(std::make_unique<mbedtls_ctr_drbg_context>()),
session_vcsec_(std::make_unique<Peer>(
UniversalMessage_Domain_DOMAIN_VEHICLE_SECURITY,
private_key_context_,
ecdh_context_,
drbg_context_)),
session_infotainment_(std::make_unique<Peer>(
UniversalMessage_Domain_DOMAIN_INFOTAINMENT,
private_key_context_,
ecdh_context_,
drbg_context_))
{
mbedtls_pk_init(private_key_context_.get());
mbedtls_ecdh_init(ecdh_context_.get());
mbedtls_ctr_drbg_init(drbg_context_.get());
}

~Client()
{
if (private_key_context_)
mbedtls_pk_free(private_key_context_.get());
if (ecdh_context_)
mbedtls_ecdh_free(ecdh_context_.get());
if (drbg_context_)
mbedtls_ctr_drbg_free(drbg_context_.get());
}

static const int MAX_BLE_MESSAGE_SIZE = 1024;

int createPrivateKey();

void generateNonce();

void setVIN(const char *vin);

void setConnectionID(const pb_byte_t *connectionID);

int loadPrivateKey(const uint8_t *private_key_buffer, size_t key_size);
int loadPrivateKey(
const uint8_t *private_key_buffer,
size_t key_size);

int getPrivateKey(pb_byte_t *output_buffer, size_t output_buffer_length,
size_t *output_length);
int getPublicKey(pb_byte_t *output_buffer, size_t *output_buffer_length);
int getPrivateKey(
pb_byte_t *output_buffer,
size_t output_buffer_length,
size_t *output_length);

int loadTeslaKey(bool isInfotainment, const uint8_t *public_key_buffer, size_t key_size);
int getPublicKey(
pb_byte_t *output_buffer,
size_t *output_buffer_length);

void cleanup();
int buildWhiteListMessage(
Keys_Role role,
VCSEC_KeyFormFactor form_factor,
pb_byte_t *output_buffer,
size_t *output_length);

int buildWhiteListMessage(Keys_Role role,
VCSEC_KeyFormFactor form_factor,
pb_byte_t *output_buffer,
size_t *output_length);
static int parseFromVCSECMessage(
UniversalMessage_RoutableMessage_protobuf_message_as_bytes_t *input_buffer,
VCSEC_FromVCSECMessage *output);

static int parseFromVCSECMessage(UniversalMessage_RoutableMessage_protobuf_message_as_bytes_t *input_buffer,
VCSEC_FromVCSECMessage *output);
static int parseUniversalMessage(
pb_byte_t *input_buffer,
size_t input_size,
UniversalMessage_RoutableMessage *output);

static int parseUniversalMessage(pb_byte_t *input_buffer,
size_t input_size,
UniversalMessage_RoutableMessage *output);
static int parseUniversalMessageBLE(
pb_byte_t *input_buffer,
size_t input_buffer_length,
UniversalMessage_RoutableMessage *output);

static int parseUniversalMessageBLE(pb_byte_t *input_buffer,
size_t input_buffer_length,
UniversalMessage_RoutableMessage *output);
static int parseVCSECInformationRequest(
UniversalMessage_RoutableMessage_protobuf_message_as_bytes_t *input_buffer,
VCSEC_InformationRequest *output);

static int parsePayloadSessionInfo(UniversalMessage_RoutableMessage_session_info_t *input_buffer,
Signatures_SessionInfo *output);
static int parsePayloadUnsignedMessage(UniversalMessage_RoutableMessage_protobuf_message_as_bytes_t *input_buffer,
VCSEC_UnsignedMessage *output);
static int parsePayloadCarServerResponse(UniversalMessage_RoutableMessage_protobuf_message_as_bytes_t *input_buffer,
CarServer_Response *output);

int buildSessionInfoRequestMessage(UniversalMessage_Domain domain,
pb_byte_t *output_buffer,
size_t *output_length);

int buildKeySummary(pb_byte_t *output_buffer,
size_t *output_length);

int buildUnsignedMessagePayload(VCSEC_UnsignedMessage *message,
pb_byte_t *output_buffer,
size_t *output_length,
bool encryptPayload = false);

int buildCarActionToMessage(CarServer_Action *action,
pb_byte_t *output_buffer,
size_t *output_length);

int buildUniversalMessageWithPayload(pb_byte_t *payload,
size_t payload_length,
UniversalMessage_Domain domain,
pb_byte_t *output_buffer,
size_t *output_length,
bool encryptPayload = false);

int buildVCSECActionMessage(const VCSEC_RKEAction_E action,
pb_byte_t *output_buffer, size_t *output_length);
int buildVCSECInformationRequestMessage(VCSEC_InformationRequestType request_type,
pb_byte_t *output_buffer,
size_t *output_length,
uint32_t key_slot = 0);

int buildCarServerActionMessage(const CarServer_VehicleAction *vehicle_action,
pb_byte_t *output_buffer,
size_t *output_length);

int buildChargingAmpsMessage(int32_t amps,
pb_byte_t *output_buffer,
size_t *output_length);

int buildChargingSetLimitMessage(int32_t percent,
pb_byte_t *output_buffer,
size_t *output_length);

int buildHVACMessage(bool isOn,
pb_byte_t *output_buffer,
size_t *output_length);

int buildWakeVehicleMessage(pb_byte_t *output_buffer,
size_t *output_length);

int buildChargingSwitchMessage(bool isOn,
pb_byte_t *output_buffer,
size_t *output_length);
static int parsePayloadSessionInfo(
UniversalMessage_RoutableMessage_session_info_t *input_buffer,
Signatures_SessionInfo *output);

static int parsePayloadUnsignedMessage(
UniversalMessage_RoutableMessage_protobuf_message_as_bytes_t *input_buffer,
VCSEC_UnsignedMessage *output);

static int parsePayloadCarServerResponse(
UniversalMessage_RoutableMessage_protobuf_message_as_bytes_t *input_buffer,
CarServer_Response *output);

int buildSessionInfoRequestMessage(
UniversalMessage_Domain domain,
pb_byte_t *output_buffer,
size_t *output_length);

int buildKeySummary(
pb_byte_t *output_buffer,
size_t *output_length);

int buildUnsignedMessagePayload(
VCSEC_UnsignedMessage *message,
pb_byte_t *output_buffer,
size_t *output_length,
bool encryptPayload = false);

int buildCarServerActionPayload(
CarServer_Action *action,
pb_byte_t *output_buffer,
size_t *output_length);

int buildUniversalMessageWithPayload(
pb_byte_t *payload,
size_t payload_length,
UniversalMessage_Domain domain,
pb_byte_t *output_buffer,
size_t *output_length,
bool encryptPayload = false);

int buildVCSECInformationRequestMessage(
VCSEC_InformationRequestType request_type,
pb_byte_t *output_buffer,
size_t *output_length,
uint32_t key_slot = 0);
int buildVCSECActionMessage(
const VCSEC_RKEAction_E action,
pb_byte_t *output_buffer, size_t *output_length);

int buildCarServerActionMessage(
const CarServer_VehicleAction *vehicle_action,
pb_byte_t *output_buffer,
size_t *output_length);

int buildChargingAmpsMessage(
int32_t amps,
pb_byte_t *output_buffer,
size_t *output_length);

int buildChargingSetLimitMessage(
int32_t percent,
pb_byte_t *output_buffer,
size_t *output_length);

int buildHVACMessage(
bool isOn,
pb_byte_t *output_buffer,
size_t *output_length);

int buildChargingSwitchMessage(
bool isOn,
pb_byte_t *output_buffer,
size_t *output_length);

Peer *getPeer(UniversalMessage_Domain domain)
{
if (domain == UniversalMessage_Domain_DOMAIN_VEHICLE_SECURITY)
{
return session_vcsec_.get();
}
else if (domain == UniversalMessage_Domain_DOMAIN_INFOTAINMENT)
{
return session_infotainment_.get();
}
return nullptr;
}

protected:
std::shared_ptr<mbedtls_pk_context> private_key_context_;
std::shared_ptr<mbedtls_ecdh_context> ecdh_context_;
std::shared_ptr<mbedtls_ctr_drbg_context> drbg_context_;
std::unique_ptr<Peer> session_vcsec_;
std::unique_ptr<Peer> session_infotainment_;

unsigned char public_key_id_[4];
unsigned char public_key_[MBEDTLS_ECP_MAX_BYTES];
size_t public_key_size_;
pb_byte_t connectionID[16];
const char *VIN = "";

static void prependLength(
const pb_byte_t *input_buffer,
size_t input_buffer_length,
pb_byte_t *output_buffer,
size_t *output_buffer_length);

int generatePublicKey();

int GenerateKeyId();
};
} // namespace TeslaBLE
// #endif // MBEDTLS_CONFIG_FILE
#endif // TESLA_BLE_CLIENT_H
Loading

0 comments on commit 4969c1a

Please sign in to comment.