diff --git a/emu/PV_BLE_cover/PV_BLE_cover.ino b/emu/PV_BLE_cover/PV_BLE_cover.ino index 1fab724..45d0da7 100644 --- a/emu/PV_BLE_cover/PV_BLE_cover.ino +++ b/emu/PV_BLE_cover/PV_BLE_cover.ino @@ -1,40 +1,58 @@ /** * Emulate a Hunter Douglas PowerView cover device using ESP32 + * used e.g. to gain the home_key from an existing installation via BLE * * TODO: - * - adding device to appartement does only work after long timeout, - * as some feedback to "reset scene automations" is expected + * - cleanup code + * - think about emulating a remote * * AUTHOR: patman15 * LICENSE: GPLv2 */ +#define NAME "myPVcover" +#define FW_VERSION "391" +#define SERIAL_NR "01234567890ABCDEF" + + #include #include #include #include +#define WOLFSSL_USER_SETTINGS +#include +#include "wolfssl/wolfcrypt/aes.h" + +Aes aes_coder; +void *hint = NULL; +int devId = INVALID_DEVID; //if not using async INVALID_DEVID is default + #include #include -#define NAME "myPVcover" - #define COVER_SERVICE_UUID "0000FDC1-0000-1000-8000-00805f9b34fb" #define COVER_CHAR_UUID "CAFE1001-C0FF-EE01-8000-A110CA7AB1E0" #define XXX_CHAR_UUID "CAFE1002-C0FF-EE01-8000-A110CA7AB1E0" -//#define FW_SERVICE_UUID "CAFE8000-C0FF-EE01-8000-A110CA7AB1E0" +#define FW_SERVICE_UUID "CAFE8000-C0FF-EE01-8000-A110CA7AB1E0" +#define FW_CHAR_UUID "CAFE8003-C0FF-EE01-8000-A110CA7AB1E0" + +#define DEV_SERVICE_UUID BLEUUID("180A") +#define SER_CHAR_UUID BLEUUID("2A25") +#define SWC_CHAR_UUID BLEUUID("2A28") #define BAT_SERVICE_UUID BLEUUID("180F") #define BAT_CHAR_UUID BLEUUID("2A19") - +#define DAT_LEN 255 #pragma pack(1) -struct header { +struct message { uint8_t serviceID; uint8_t cmdID; uint8_t sequence; uint8_t data_len; + uint8_t data[DAT_LEN]; }; struct position { @@ -46,166 +64,279 @@ struct position { }; struct notification { - uint8_t *data; - BLECharacteristic *characteristic; + uint8_t *data; + BLECharacteristic *characteristic; }; BLECharacteristic *pCharacteristic_cover, *pCharacteristic_fw, *pCharacteristic_unknown, *pCharacteristic_bat; +BLECharacteristic *pCharacteristic_dev, *pCharacteristic_ser; BLEServer *pServer = NULL; bool deviceConnected = false; bool oldDeviceConnected = false; struct notification rx_data; volatile bool data_available = false; -uint8_t buffer[20]; +const byte zero_key[16] = { 0 }; +byte home_key[16] = { 0 }; -const char* dec_cmd(uint16_t cmd) { - switch(cmd) { - case 0x01: - return "set position"; - case 0xBA: - return "activate scene"; - default: - return "ERR"; - } -} - -void print_hex(uint8_t *value, uint8_t len) { - for (int i = 0; i < len; i++) { - Serial.print("0x"); - Serial.print(value[i], HEX); - Serial.print(" "); - } - Serial.println(""); -} - -class MyServerCallbacks: public BLEServerCallbacks { - void onConnect(BLEServer* pServer) { - Serial.print("connect ID: "); - Serial.println(pServer->getConnId()); - /*pServer->updatePeerMTU(pServer->getConnId(), 310); - Serial.print("MTU: "); - Serial.println(pServer->getPeerMTU(pServer->getConnId()));*/ - deviceConnected = true; - BLEDevice::startAdvertising(); - }; - - void onDisconnect(BLEServer* pServer) { - Serial.println("disconnect."); - deviceConnected = false; - } - - void onMtuChanged(BLEServer* pServer, esp_ble_gatts_cb_param_t* param) { - Serial.printf("MTU changed: %d\n", pServer->getPeerMTU(pServer->getConnId())); - } +const char *BLEstate[] = { + "SUCCESS_INDICATE", + "SUCCESS_NOTIFY", + "ERROR_INDICATE_DISABLED", + "ERROR_NOTIFY_DISABLED", + "ERROR_GATT", + "ERROR_NO_CLIENT", + "ERROR_INDICATE_TIMEOUT", + "ERROR_INDICATE_FAILURE" }; -void decode() { - Serial.printf("Cover write %s:\n\t", rx_data.characteristic->toString().c_str()); - print_hex(rx_data.characteristic->getData(), rx_data.characteristic->getLength()); - - if (rx_data.characteristic->getLength() < 4) return; - - struct header data; - memcpy((void *) &data, rx_data.characteristic->getData(), 4); - Serial.printf("SRV: %x, CMD %x, SEQ %x, LEN %x\n", data.serviceID, data.cmdID, data.sequence, data.data_len); - - switch ((data.serviceID << 8) | data.cmdID) { - case 0xF701: - // set position - struct position pos; - memcpy((void *) &pos, &rx_data.data[4], data.data_len); - Serial.printf("\tset position\tpos1 %f%%, pos2 %d, pos3 %d, tilt %d, velocity %d\n", pos.pos1/100.0, pos.pos2, pos.pos3, pos.tilt, pos.velocity); - break; - case 0xF7B8: - // stop movement - Serial.println("\tstop"); - break; - case 0xF7BA: - // activate scene - Serial.printf("\tactivate scene\tscene #%d\n", (uint16_t) rx_data.data[4]); - break; - case 0xFA5B: - // get scene - Serial.printf("\tget scene\tscene #%d\n", (uint16_t) rx_data.data[4]); - break; - case 0xFAEA: - // Reset Scene Automations - // FIXME! wrong return value! - const uint8_t ret_val[] = {0xEA, 0xEA, data.sequence, 0x1, 0x0}; - Serial.println("\treset scene automations:"); - memcpy(&buffer, ret_val, 5); - delay(100); - Serial.print("\t\tret value: "); - print_hex(buffer, 5); - rx_data.characteristic->setValue((uint8_t *) &buffer, 5); - rx_data.characteristic->notify(); - break; - } - Serial.println(); - +void print_hex(const uint8_t *value, uint8_t len, const char *prefix = "0x", const char *postfix = " ") { + for (int i = 0; i < len; i++) { + Serial.printf("%s%02X%s", prefix, value[i], postfix); + } + Serial.println(); } -class coverCallbacks: public BLECharacteristicCallbacks { +uint8_t set_response(message *response, const message *request, const byte *data = NULL, const uint8_t data_len = 1) { + const uint8_t message_len = min(data_len, (uint8_t)DAT_LEN) + sizeof(struct message) - DAT_LEN; + response->serviceID = request->serviceID & 0xEF; + response->cmdID = request->cmdID; + response->sequence = request->sequence; + response->data_len = min(data_len, (uint8_t)DAT_LEN); + if (data) { + memcpy(response->data, data, std::min(data_len, (uint8_t)DAT_LEN)); + } else { + *response->data = 0x0; + } + Serial.printf("\tret value (%i): ", message_len); + print_hex((const uint8_t *)response, message_len); + if (memcmp(home_key, zero_key, sizeof(zero_key))) { + message unencrypted; + memcpy(&unencrypted, response, message_len); + // AES counter is reset every message, so we need to init it each time + if (wc_AesInit(&aes_coder, hint, devId) || wc_AesSetKey(&aes_coder, (const byte *)home_key, 16, zero_key, AES_ENCRYPTION)) { + Serial.println("FATAL: setting AES init failed!"); + return 0; + } + if (wc_AesCtrEncrypt(&aes_coder, (byte *)response, (const byte *)&unencrypted, message_len)) { + Serial.println(F("FATAL: encryption failed!")); + return 0; + } + Serial.printf("\tencrypted (%i): ", message_len); + print_hex((const uint8_t *)response, message_len); + } + return message_len; +} + +void decode(BLECharacteristic *pChar) { + message response; + byte data_dec[DAT_LEN]; + const uint16_t data_len = pChar->getLength(); + const byte *data_raw = pChar->getData(); + struct message msg; + uint8_t resp_size = 0; + + Serial.print("\t BLE data: "); + print_hex(data_raw, data_len); + + if (data_len < 4) return; + + if (memcmp(home_key, zero_key, sizeof(zero_key))) { + if (wc_AesInit(&aes_coder, hint, devId) || wc_AesSetKey(&aes_coder, (const byte *)home_key, 16, zero_key, AES_ENCRYPTION)) { + Serial.println("FATAL: setting AES init failed!"); + } + if (wc_AesCtrEncrypt(&aes_coder, data_dec, data_raw, data_len)) { + Serial.println(F("FATAL: decryption failed!")); + return; + } + Serial.print("\tdecrypted: "); + print_hex(data_dec, data_len); + } else { + memcpy(data_dec, data_raw, data_len); + } + + memcpy((void *)&msg, data_dec, 4); + Serial.printf("\t message: SRV: %02x, CMD %02x, SEQ %i, LEN %i\n", msg.serviceID, msg.cmdID, msg.sequence, msg.data_len); + + // sepecial responses (static data!) + const byte ret_valF1DD[] = { 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // product info + const byte ret_valFFDD[] = { 0x00, 0x05, 0xd1, 0xa2, 0x9a, 0x42, 0x59, 0x5d, 0x5c, 0x52, 0x1b, 0x00, 0x00, 0x00, 0x87, 0x01, 0x00, 0x00, 0x5f, 0x9c, 0x02, 0x00, 0x5f, 0x9c, 0x02, 0x00, 0x2a, 0xe0, 0x08 }; // HW diagnostics + const byte ret_valFFDE[] = { 0x08, 0x00, 0x02, 0x26, 0x72, 0x01, 0x59, 0x01, 0x00 }; // power status + const byte ret_valFA5B[] = { 0x00, 0x0a, 0xa2, 0x88, 0x13, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // get scene + const byte ret_valFA5A[] = { 0x00, 0x02, 0xb0 }; // set scene + + Serial.print("\t\t"); + switch ((msg.serviceID << 8) | msg.cmdID) { + case 0xF1DD: + Serial.println("get product info."); + resp_size = set_response(&response, (const message *)data_dec, ret_valF1DD, sizeof(ret_valF1DD)); + break; + case 0xF701: + // set position + struct position pos; + memcpy((void *)&pos, &data_dec[4], msg.data_len); + Serial.printf("set position: pos1 %f%%, pos2 %d, pos3 %d, tilt %d, velocity %d\n", pos.pos1 / 100.0, pos.pos2, pos.pos3, pos.tilt, pos.velocity); + break; + case 0xF711: + // identify + Serial.printf("identify: %i\n", data_dec[4]); + resp_size = set_response(&response, (const message *)data_dec); + break; + case 0xF7B8: + // stop movement + Serial.println("stop."); + break; + case 0xF7BA: + // activate scene + Serial.printf("activate scene #%i\n", data_dec[4]); + break; + case 0xFA5A: + // set scene + Serial.printf("set scene #%i\n", data_dec[4]); + resp_size = set_response(&response, (const message *)data_dec, ret_valFA5A, sizeof(ret_valFA5A)); + break; + case 0xFA5B: + // get scene + Serial.printf("get scene #%i\n", data_dec[4]); + resp_size = set_response(&response, (const message *)data_dec, ret_valFA5B, sizeof(ret_valFA5B)); + break; + case 0xFAEA: + // Reset Scene Automations + Serial.println("reset scene automations:"); + resp_size = set_response(&response, (const message *)data_dec); + break; + case 0xFB02: + // set shade key + Serial.print("set shade key: "); + print_hex(&data_raw[4], data_len - 4, "\\x"); + // set resonse before key, to acknowledge unencrypted + resp_size = set_response(&response, (const message *)data_dec); + if (msg.data_len == 16) { + memcpy(home_key, &data_raw[4], 16); + } + break; + // case 0xFF67: + // // get shade time + // break; + case 0xFF77: + // set shade time + Serial.printf("set time: %i-%i-%i %i:%i:%i\n", data_dec[4] | data_dec[5] << 8, data_dec[6], data_dec[7], data_dec[8], data_dec[9], data_dec[10]); + resp_size = set_response(&response, (const message *)data_dec); + break; + case 0xFF87: + Serial.printf("set sunrise %i:%i:%i, sunset %i:%i:%i\n", data_dec[4], data_dec[5], data_dec[6], data_dec[7], data_dec[8], data_dec[9]); + resp_size = set_response(&response, (const message *)data_dec); + break; + case 0xFFD7: + Serial.printf("set shade configuration: 0x%02X, status LED: %s\n", data_dec[4], data_dec[5] ? "on" : "off"); + resp_size = set_response(&response, (const message *)data_dec); + break; + case 0xFFDD: + // get HW diagnostics + Serial.println("get HW diagnostics."); + resp_size = set_response(&response, (const message *)data_dec, ret_valFFDD, sizeof(ret_valFFDD)); + break; + case 0xFFDE: + // get power status + Serial.println("get power status."); + resp_size = set_response(&response, (const message *)&data_dec, ret_valFFDE, sizeof(ret_valFFDE)); + break; + case 0xFFDF: + // set power type + Serial.printf("set power type: %i\n", data_dec[4]); + resp_size = set_response(&response, (const message *)data_dec); + break; + case 0xFFEE: + Serial.println("factory reset."); + resp_size = set_response(&response, (const message *)data_dec); + break; + default: + Serial.println(F("*********************************** unknown message")); + } + if (resp_size) { + pChar->setValue((uint8_t *)&response, resp_size); + pChar->notify(); + } +} + +class MyServerCallbacks : public BLEServerCallbacks { + void onConnect(BLEServer *pServer) { + digitalWrite(LED_BUILTIN, HIGH); + Serial.printf("connect ID: %i\n", pServer->getConnId()); + deviceConnected = true; + BLEDevice::startAdvertising(); + }; + + void onDisconnect(BLEServer *pServer) { + digitalWrite(LED_BUILTIN, LOW); + Serial.printf("disconnect ID: %i\n\n", pServer->getConnId()); + deviceConnected = false; + } + + void onMtuChanged(BLEServer *pServer, esp_ble_gatts_cb_param_t *param) { + Serial.printf("MTU changed: %d\n", pServer->getPeerMTU(pServer->getConnId())); + } +}; + +class coverCallbacks : public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { - rx_data.characteristic = pCharacteristic; - data_available = true; + Serial.printf("Cover write %s\n", pCharacteristic->toString().c_str()); + decode(pCharacteristic); } void onRead(BLECharacteristic *pCharacteristic) { - Serial.printf("Cover read: %s\n", pCharacteristic->toString().c_str()); + Serial.printf("Cover read: %s\n", pCharacteristic->toString().c_str()); + } + + void onNotify(BLECharacteristic *pCharacteristic) { + Serial.printf("Cover onNotify() %s\n", pCharacteristic->toString().c_str()); } - void onNotify(BLECharacteristic *pCharacteristic){ - Serial.println("onNotify()"); - } // not used - void onStatus(BLECharacteristic *pCharacteristic, Status s, uint32_t code){ - Serial.println("onStatus()"); - }; // not used - + void onStatus(BLECharacteristic *pCharacteristic, Status s, uint32_t code) { + Serial.printf("Cover onStatus() %s: %s\n", BLEstate[s], pCharacteristic->toString().c_str()); + } }; -class batteryCallbacks: public BLECharacteristicCallbacks { - +class batteryCallbacks : public BLECharacteristicCallbacks { + void onWrite(BLECharacteristic *pCharacteristic) { uint8_t *value = pCharacteristic->getData(); - Serial.printf("Battery write: %s:", pCharacteristic->toString().c_str()); + Serial.printf("Battery write: %s:", pCharacteristic->toString().c_str()); print_hex(value, pCharacteristic->getLength()); Serial.println(); - } - - void onRead(BLECharacteristic *pCharacteristic) { - Serial.printf("Battery read: %s\n", pCharacteristic->toString().c_str()); } - void onNotify(BLECharacteristic *pCharacteristic){ + void onRead(BLECharacteristic *pCharacteristic) { + Serial.printf("Battery read: %s\n", pCharacteristic->toString().c_str()); + } + + void onNotify(BLECharacteristic *pCharacteristic) { Serial.println("Battery onNotify()"); - } // not used - void onStatus(BLECharacteristic *pCharacteristic, Status s, uint32_t code){ + } + void onStatus(BLECharacteristic *pCharacteristic, Status s, uint32_t code) { Serial.println("Battery onStatus()"); - }; // not used + } }; -class genericCallbacks: public BLECharacteristicCallbacks { - +class genericCallbacks : public BLECharacteristicCallbacks { + void onWrite(BLECharacteristic *pCharacteristic) { //uint8_t *value = pCharacteristic->getData(); - Serial.printf("generic write %s:", pCharacteristic->toString().c_str()); + Serial.printf("generic write %s:\n", pCharacteristic->toString().c_str()); //print_hex(value, pCharacteristic->getLength()); - Serial.println(); - } + } void onRead(BLECharacteristic *pCharacteristic) { - Serial.printf("generic read %s.\n", pCharacteristic->toString().c_str()); + Serial.printf("generic read %s.\n", pCharacteristic->toString().c_str()); } - void onNotify(BLECharacteristic *pCharacteristic){ - Serial.println("generic onNotify()"); - } // not used - void onStatus(BLECharacteristic *pCharacteristic, Status s, uint32_t code){ - Serial.println("generic onStatus()"); - }; // not used + void onNotify(BLECharacteristic *pCharacteristic) { + Serial.printf("generic onNotify() %s\n", pCharacteristic->toString().c_str()); + } // not used + void onStatus(BLECharacteristic *pCharacteristic, Status s, uint32_t code) { + Serial.printf("generic onStatus() %s - %s\n", BLEstate[s], pCharacteristic->toString().c_str()); + }; // not used }; void setup() { @@ -221,70 +352,73 @@ void setup() { BLEService *pCovService = pServer->createService(COVER_SERVICE_UUID); // Create a BLE Characteristic pCharacteristic_cover = pCovService->createCharacteristic( - COVER_CHAR_UUID, - BLECharacteristic::PROPERTY_NOTIFY | - BLECharacteristic::PROPERTY_WRITE | - BLECharacteristic::PROPERTY_WRITE_NR - ); + COVER_CHAR_UUID, + BLECharacteristic::PROPERTY_NOTIFY | BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_WRITE_NR); pCharacteristic_cover->setCallbacks(new coverCallbacks()); // Create a BLE Descriptor /* BLEDescriptor *pDesc1 = new BLEDescriptor("2901", 10); - pDesc1->setValue("cover");*/ +pDesc1->setValue("cover");*/ //pCharacteristic_cover->addDescriptor(pDesc1); pCharacteristic_cover->addDescriptor(new BLE2902()); - - + + pCharacteristic_unknown = pCovService->createCharacteristic( - XXX_CHAR_UUID, - BLECharacteristic::PROPERTY_NOTIFY | - BLECharacteristic::PROPERTY_WRITE | - BLECharacteristic::PROPERTY_WRITE_NR - ); + XXX_CHAR_UUID, + BLECharacteristic::PROPERTY_NOTIFY | BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_WRITE_NR); pCharacteristic_unknown->setCallbacks(new genericCallbacks()); pCharacteristic_unknown->addDescriptor(new BLE2902()); - - // BLEService *pBatService = pServer->createService(BAT_SERVICE_UUID); - - // pCharacteristic_bat = pBatService->createCharacteristic( - // BAT_CHAR_UUID, - // BLECharacteristic::PROPERTY_READ - // ); - // pCharacteristic_bat->setCallbacks(new batteryCallbacks()); - // uint8_t battery_level = 42; - // pCharacteristic_bat->setValue(&battery_level, 1); - // pCharacteristic_bat->addDescriptor(new BLE2902()); - // BLEService *pFWService = pServer->createService(FW_SERVICE_UUID); - // pCharacteristic_fw = pCovService->createCharacteristic( - // CHAR_FW_UUID, - // BLECharacteristic::PROPERTY_READ | - // BLECharacteristic::PROPERTY_WRITE | - // BLECharacteristic::PROPERTY_WRITE_NR - // ); - // pCharacteristic_fw->setCallbacks(new genericCallbacks()); - // pCharacteristic_fw->addDescriptor(new BLE2902()); - // pCharacteristic_fw->addDescriptor(pDesc2); - //BLEDescriptor *pDesc2 = new BLEDescriptor("2901", 10); - //pDesc2->setValue("firmware"); + BLEService *pBatService = pServer->createService(BAT_SERVICE_UUID); + pCharacteristic_bat = pBatService->createCharacteristic( + BAT_CHAR_UUID, + BLECharacteristic::PROPERTY_READ); + pCharacteristic_bat->setCallbacks(new batteryCallbacks()); + uint8_t battery_level = 42; + pCharacteristic_bat->setValue(&battery_level, 1); + pCharacteristic_bat->addDescriptor(new BLE2902()); - // Start the service + BLEService *pFWService = pServer->createService(FW_SERVICE_UUID); + pCharacteristic_fw = pFWService->createCharacteristic( + FW_CHAR_UUID, + BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_WRITE_NR); + pCharacteristic_fw->setCallbacks(new genericCallbacks()); + pCharacteristic_fw->addDescriptor(new BLE2902()); + BLEDescriptor *pDesc2 = new BLEDescriptor("2901", 10); + pDesc2->setValue("firmware"); + pCharacteristic_fw->addDescriptor(pDesc2); + + + BLEService *pDEVService = pServer->createService(DEV_SERVICE_UUID); + pCharacteristic_dev = pDEVService->createCharacteristic( + SWC_CHAR_UUID, + BLECharacteristic::PROPERTY_READ); + pCharacteristic_dev->setValue(FW_VERSION); + pCharacteristic_dev->setCallbacks(new genericCallbacks()); + pCharacteristic_ser = pDEVService->createCharacteristic( + SER_CHAR_UUID, + BLECharacteristic::PROPERTY_READ); + pCharacteristic_ser->setValue(SERIAL_NR); + pCharacteristic_ser->setCallbacks(new genericCallbacks()); + + // Start the services pCovService->start(); - //pFWService->start(); + pFWService->start(); + pBatService->start(); + pDEVService->start(); // Start advertising BLEAdvertisementData AdvertisementData; - const String manufacturerData = String("\x19\x08\x00\x00\x2A\x00\x00\x00\x00\x00\xA2",11); - // Hunter Douglas ^^--^^ ^^ ID-Type + const String manufacturerData = String("\x19\x08\x00\x00\x2A\x00\x00\x00\x00\x00\xA2", 11); + // Hunter Douglas ^^--^^ ^^key^^ ^^ ID-Type AdvertisementData.setManufacturerData(manufacturerData); AdvertisementData.setPartialServices(BLEUUID(COVER_SERVICE_UUID)); - AdvertisementData.setFlags((1 << 2) | (1 << 1)); // [BR/EDR Not Supported] | [LE General Discoverable Mode] + AdvertisementData.setFlags((1 << 2) | (1 << 1)); // [BR/EDR Not Supported] | [LE General Discoverable Mode] BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); pAdvertising->setAdvertisementData(AdvertisementData); - BLEDevice::startAdvertising(); - + Serial.println("Device " NAME " ready."); } @@ -301,10 +435,5 @@ void loop() { if (deviceConnected && !oldDeviceConnected) { // do stuff here on connecting oldDeviceConnected = deviceConnected; - } - if (deviceConnected && data_available) { - data_available = false; - decode(); - delay(100); } } diff --git a/emu/PV_BLE_cover/user_settings.h b/emu/PV_BLE_cover/user_settings.h new file mode 100644 index 0000000..b170315 --- /dev/null +++ b/emu/PV_BLE_cover/user_settings.h @@ -0,0 +1,540 @@ +/* user_settings_template.h + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* Example wolfSSL user settings with #if 0/1 gates to enable/disable algorithms and features. + * This file is included with wolfssl/wolfcrypt/settings.h when WOLFSSL_USER_SETTINGS is defined. + * Based on IDE/GCC-ARM/Headers/user_settings.h + */ + +#ifndef WOLFSSL_USER_SETTINGS_H +#define WOLFSSL_USER_SETTINGS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* If TARGET_EMBEDDED is defined then small target settings are used */ +#if !(defined(__MACH__) || defined(__FreeBSD__) || defined(__linux__) || defined(_WIN32)) + #define TARGET_EMBEDDED +#endif + +/* ------------------------------------------------------------------------- */ +/* Platform */ +/* ------------------------------------------------------------------------- */ +#define WOLFSSL_GENERAL_ALIGNMENT 4 +#define SIZEOF_LONG_LONG 8 +#if 0 + #define NO_64BIT /* disable use of 64-bit variables */ +#endif + +#ifdef TARGET_EMBEDDED + /* disable mutex locking */ + #define SINGLE_THREADED + + /* reduce stack use. For variables over 100 bytes allocate from heap */ + #define WOLFSSL_SMALL_STACK + + /* Disable the built-in socket support and use the IO callbacks. + * Set IO callbacks with wolfSSL_CTX_SetIORecv/wolfSSL_CTX_SetIOSend + */ + #define WOLFSSL_USER_IO +#endif + +/* ------------------------------------------------------------------------- */ +/* Math Configuration */ +/* ------------------------------------------------------------------------- */ +/* Wolf Single Precision Math */ +#if 1 + #define WOLFSSL_HAVE_SP_RSA + #define WOLFSSL_HAVE_SP_DH + #define WOLFSSL_HAVE_SP_ECC + //#define WOLFSSL_SP_4096 /* Enable RSA/RH 4096-bit support */ + //#define WOLFSSL_SP_384 /* Enable ECC 384-bit SECP384R1 support */ + + //#define WOLFSSL_SP_MATH /* only SP math - disables integer.c/tfm.c */ + #define WOLFSSL_SP_MATH_ALL /* use SP math for all key sizes and curves */ + + //#define WOLFSSL_SP_NO_MALLOC + //#define WOLFSSL_SP_DIV_32 /* do not use 64-bit divides */ + + #ifdef TARGET_EMBEDDED + /* use smaller version of code */ + #define WOLFSSL_SP_SMALL + #else + /* SP Assembly Speedups - specific to chip type */ + #define WOLFSSL_SP_ASM + #endif + //#define WOLFSSL_SP_X86_64 + //#define WOLFSSL_SP_X86 + //#define WOLFSSL_SP_ARM32_ASM + //#define WOLFSSL_SP_ARM64_ASM + //#define WOLFSSL_SP_ARM_THUMB_ASM + //#define WOLFSSL_SP_ARM_CORTEX_M_ASM +#elif 1 + /* Fast Math (tfm.c) (stack based and timing resistant) */ + #define USE_FAST_MATH + #define TFM_TIMING_RESISTANT +#else + /* Normal (integer.c) (heap based, not timing resistant) - not recommended*/ + #define USE_INTEGER_HEAP_MATH +#endif + + +/* ------------------------------------------------------------------------- */ +/* Crypto */ +/* ------------------------------------------------------------------------- */ +/* RSA */ +#undef NO_RSA +#if 0 + #ifdef USE_FAST_MATH + /* Maximum math bits (Max RSA key bits * 2) */ + #define FP_MAX_BITS 4096 + #endif + + /* half as much memory but twice as slow */ + //#define RSA_LOW_MEM + + /* Enables blinding mode, to prevent timing attacks */ + #define WC_RSA_BLINDING + + /* RSA PSS Support */ + #define WC_RSA_PSS +#else + #define NO_RSA +#endif + +/* DH */ +#undef NO_DH +#if 0 + /* Use table for DH instead of -lm (math) lib dependency */ + #if 1 + #define WOLFSSL_DH_CONST + #define HAVE_FFDHE_2048 + //#define HAVE_FFDHE_4096 + //#define HAVE_FFDHE_6144 + //#define HAVE_FFDHE_8192 + #endif +#else + #define NO_DH +#endif + +/* ECC */ +#undef HAVE_ECC +#if 0 + #define HAVE_ECC + + /* Manually define enabled curves */ + #define ECC_USER_CURVES + + #ifdef ECC_USER_CURVES + /* Manual Curve Selection */ + //#define HAVE_ECC192 + //#define HAVE_ECC224 + #undef NO_ECC256 + //#define HAVE_ECC384 + //#define HAVE_ECC521 + #endif + + /* Fixed point cache (speeds repeated operations against same private key) */ + //#define FP_ECC + #ifdef FP_ECC + /* Bits / Entries */ + #define FP_ENTRIES 2 + #define FP_LUT 4 + #endif + + /* Optional ECC calculation method */ + /* Note: doubles heap usage, but slightly faster */ + #define ECC_SHAMIR + + /* Reduces heap usage, but slower */ + #define ECC_TIMING_RESISTANT + + /* Compressed ECC Key Support */ + //#define HAVE_COMP_KEY + + /* Use alternate ECC size for ECC math */ + #ifdef USE_FAST_MATH + /* MAX ECC BITS = ROUND8(MAX ECC) * 2 */ + #if defined(NO_RSA) && defined(NO_DH) + /* Custom fastmath size if not using RSA/DH */ + #define FP_MAX_BITS (256 * 2) + #else + /* use heap allocation for ECC points */ + #define ALT_ECC_SIZE + + /* wolfSSL will compute the FP_MAX_BITS_ECC, but it can be overridden */ + //#define FP_MAX_BITS_ECC (256 * 2) + #endif + + /* Speedups specific to curve */ + #ifndef NO_ECC256 + #define TFM_ECC256 + #endif + #endif +#endif + + +/* AES */ +#undef NO_AES +#if 1 + #define HAVE_AES_CBC + + /* GCM Method: GCM_TABLE_4BIT, GCM_SMALL, GCM_WORD32 or GCM_TABLE */ + #define HAVE_AESGCM + #ifdef TARGET_EMBEDDED + #define GCM_SMALL + #else + #define GCM_TABLE_4BIT + #endif + + #define WOLFSSL_AES_DIRECT + //#define HAVE_AES_ECB + #define WOLFSSL_AES_COUNTER + //#define HAVE_AESCCM +#else + #define NO_AES +#endif + + +/* DES3 */ +#undef NO_DES3 +#if 0 +#else + #define NO_DES3 +#endif + +/* ChaCha20 / Poly1305 */ +#undef HAVE_CHACHA +#undef HAVE_POLY1305 +#if 0 + #define HAVE_CHACHA + #define HAVE_POLY1305 + + /* Needed for Poly1305 */ + #define HAVE_ONE_TIME_AUTH +#endif + +/* Ed25519 / Curve25519 */ +#undef HAVE_CURVE25519 +#undef HAVE_ED25519 +#if 0 + #define HAVE_CURVE25519 + #define HAVE_ED25519 /* ED25519 Requires SHA512 */ + + /* Optionally use small math (less flash usage, but much slower) */ + #if 1 + #define CURVED25519_SMALL + #endif +#endif + + +/* ------------------------------------------------------------------------- */ +/* Hashing */ +/* ------------------------------------------------------------------------- */ +/* Sha */ +#undef NO_SHA +#if 1 + /* 1k smaller, but 25% slower */ + //#define USE_SLOW_SHA +#else + #define NO_SHA +#endif + +/* Sha256 */ +#undef NO_SHA256 +#if 1 + /* not unrolled - ~2k smaller and ~25% slower */ + //#define USE_SLOW_SHA256 + + /* Sha224 */ + #if 0 + #define WOLFSSL_SHA224 + #endif +#else + #define NO_SHA256 +#endif + +/* Sha512 */ +#undef WOLFSSL_SHA512 +#if 0 + #define WOLFSSL_SHA512 + + /* Sha384 */ + #undef WOLFSSL_SHA384 + #if 0 + #define WOLFSSL_SHA384 + #endif + + /* over twice as small, but 50% slower */ + //#define USE_SLOW_SHA512 +#endif + +/* Sha3 */ +#undef WOLFSSL_SHA3 +#if 0 + #define WOLFSSL_SHA3 +#endif + +/* MD5 */ +#undef NO_MD5 +#if 0 + +#else + #define NO_MD5 +#endif + +/* HKDF */ +#undef HAVE_HKDF +#if 0 + #define HAVE_HKDF +#endif + +/* CMAC */ +#undef WOLFSSL_CMAC +#if 0 + #define WOLFSSL_CMAC +#endif + + +/* ------------------------------------------------------------------------- */ +/* Benchmark / Test */ +/* ------------------------------------------------------------------------- */ +#ifdef TARGET_EMBEDDED + /* Use reduced benchmark / test sizes */ + #define BENCH_EMBEDDED +#endif + +/* Use test buffers from array (not filesystem) */ +#ifndef NO_FILESYSTEM +#define USE_CERT_BUFFERS_256 +#define USE_CERT_BUFFERS_2048 +#endif + +/* ------------------------------------------------------------------------- */ +/* Debugging */ +/* ------------------------------------------------------------------------- */ + +#undef DEBUG_WOLFSSL +#undef NO_ERROR_STRINGS +#if 0 + #define DEBUG_WOLFSSL +#else + #if 0 + #define NO_ERROR_STRINGS + #endif +#endif + + +/* ------------------------------------------------------------------------- */ +/* Memory */ +/* ------------------------------------------------------------------------- */ + +/* Override Memory API's */ +#if 0 + #define XMALLOC_OVERRIDE + + /* prototypes for user heap override functions */ + /* Note: Realloc only required for normal math */ + /* Note2: XFREE(NULL) must be properly handled */ + #include /* for size_t */ + extern void *myMalloc(size_t n, void* heap, int type); + extern void myFree(void *p, void* heap, int type); + extern void *myRealloc(void *p, size_t n, void* heap, int type); + + #define XMALLOC(n, h, t) myMalloc(n, h, t) + #define XFREE(p, h, t) myFree(p, h, t) + #define XREALLOC(p, n, h, t) myRealloc(p, n, h, t) +#endif + +#if 0 + /* Static memory requires fast math */ + #define WOLFSSL_STATIC_MEMORY + + /* Disable fallback malloc/free */ + #define WOLFSSL_NO_MALLOC + #if 1 + #define WOLFSSL_MALLOC_CHECK /* trap malloc failure */ + #endif +#endif + +/* Memory callbacks */ +#if 0 + #undef USE_WOLFSSL_MEMORY + #define USE_WOLFSSL_MEMORY + + /* Use this to measure / print heap usage */ + #if 0 + #define WOLFSSL_TRACK_MEMORY + #define WOLFSSL_DEBUG_MEMORY + #endif +#else + #ifndef WOLFSSL_STATIC_MEMORY + #define NO_WOLFSSL_MEMORY + /* Otherwise we will use stdlib malloc, free and realloc */ + #endif +#endif + + +/* ------------------------------------------------------------------------- */ +/* Port */ +/* ------------------------------------------------------------------------- */ + +/* Override Current Time */ +#if 0 + /* Allows custom "custom_time()" function to be used for benchmark */ + #define WOLFSSL_USER_CURRTIME + #define WOLFSSL_GMTIME + #define USER_TICKS + extern unsigned long my_time(unsigned long* timer); + #define XTIME my_time +#endif + + +/* ------------------------------------------------------------------------- */ +/* RNG */ +/* ------------------------------------------------------------------------- */ + +/* Choose RNG method */ +#if 0 + /* Custom Seed Source */ + #if 0 + /* Size of returned HW RNG value */ + #define CUSTOM_RAND_TYPE unsigned int + extern unsigned int my_rng_seed_gen(void); + #undef CUSTOM_RAND_GENERATE + #define CUSTOM_RAND_GENERATE my_rng_seed_gen + #endif + + /* Use built-in P-RNG (SHA256 based) with HW RNG */ + /* P-RNG + HW RNG (P-RNG is ~8K) */ + #undef HAVE_HASHDRBG + #define HAVE_HASHDRBG +#else + #undef WC_NO_HASHDRBG + #define WC_NO_HASHDRBG + + /* Bypass P-RNG and use only HW RNG */ + extern int my_rng_gen_block(unsigned char* output, unsigned int sz); + #undef CUSTOM_RAND_GENERATE_BLOCK + #define CUSTOM_RAND_GENERATE_BLOCK my_rng_gen_block +#endif + + +/* ------------------------------------------------------------------------- */ +/* Custom Standard Lib */ +/* ------------------------------------------------------------------------- */ +/* Allows override of all standard library functions */ +#undef STRING_USER +#if 0 + #define STRING_USER + + #include + + #define USE_WOLF_STRSEP + #define XSTRSEP(s1,d) wc_strsep((s1),(d)) + + #define USE_WOLF_STRTOK + #define XSTRTOK(s1,d,ptr) wc_strtok((s1),(d),(ptr)) + + #define XSTRNSTR(s1,s2,n) mystrnstr((s1),(s2),(n)) + + #define XMEMCPY(d,s,l) memcpy((d),(s),(l)) + #define XMEMSET(b,c,l) memset((b),(c),(l)) + #define XMEMCMP(s1,s2,n) memcmp((s1),(s2),(n)) + #define XMEMMOVE(d,s,l) memmove((d),(s),(l)) + + #define XSTRLEN(s1) strlen((s1)) + #define XSTRNCPY(s1,s2,n) strncpy((s1),(s2),(n)) + #define XSTRSTR(s1,s2) strstr((s1),(s2)) + + #define XSTRNCMP(s1,s2,n) strncmp((s1),(s2),(n)) + #define XSTRNCAT(s1,s2,n) strncat((s1),(s2),(n)) + #define XSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n)) + + #define XSNPRINTF snprintf +#endif + + + +/* ------------------------------------------------------------------------- */ +/* Enable Features */ +/* ------------------------------------------------------------------------- */ + +#define WOLFSSL_TLS13 +#define WOLFSSL_OLD_PRIME_CHECK /* Use faster DH prime checking */ +#define HAVE_TLS_EXTENSIONS +#define HAVE_SUPPORTED_CURVES +#define WOLFSSL_BASE64_ENCODE + +//#define WOLFSSL_KEY_GEN /* For RSA Key gen only */ +//#define KEEP_PEER_CERT +//#define HAVE_COMP_KEY + +/* TLS Session Cache */ +#if 0 + #define SMALL_SESSION_CACHE +#else + #define NO_SESSION_CACHE +#endif + + +/* ------------------------------------------------------------------------- */ +/* Disable Features */ +/* ------------------------------------------------------------------------- */ +#define NO_WOLFSSL_SERVER +#define NO_WOLFSSL_CLIENT +//#define NO_CRYPT_TEST +//#define NO_CRYPT_BENCHMARK +#define WOLFCRYPT_ONLY + +/* do not warm when file is included to be built and not required to be */ +#define WOLFSSL_IGNORE_FILE_WARN + +/* In-lining of misc.c functions */ +/* If defined, must include wolfcrypt/src/misc.c in build */ +/* Slower, but about 1k smaller */ +//#define NO_INLINE + +#ifdef TARGET_EMBEDDED + #define NO_FILESYSTEM + #define NO_WRITEV + #define NO_MAIN_DRIVER + #define NO_DEV_RANDOM +#endif + +#define NO_OLD_TLS +#define NO_PSK + +#define NO_DSA +#define NO_RC4 +#define NO_MD4 +#define NO_PWDBASED +//#define NO_CODING +//#define NO_ASN_TIME +//#define NO_CERTS +//#define NO_SIG_WRAPPER + +#ifdef __cplusplus +} +#endif + +#endif /* WOLFSSL_USER_SETTINGS_H */ \ No newline at end of file