diff --git a/BUILDS.md b/BUILDS.md index 91bbd287e..700407907 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -77,6 +77,7 @@ | USE_MAX31855 | - | - | - | - | x | - | - | | USE_MAX31865 | - | - | - | - | - | - | - | | USE_THERMOSTAT | - | - | - | - | - | - | - | +| USE_LMT01 | - | - | - | - | x | - | - | | | | | | | | | | | Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks | USE_I2C | - | - | x | x | x | - | x | @@ -181,3 +182,4 @@ |-----------------------|---------|-------|--------|-----|---------|----|---------|--------|-------- | USE_MI_ESP32 | - | - | - | - | - | - | - | - | | USE_WEBCAM | - | - | - | - | - | - | - | x | +| USE_ETHERNET | - | - | - | - | - | - | - | - | diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 94275b2bd..410ecc1d1 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -52,16 +52,20 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ## Changelog -### Version 8.3.1.5 +### Version 8.3.1.6 - Change IRremoteESP8266 library updated to v2.7.7 - Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) - Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` - Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]`` +- Change ESP32 USER GPIO template representation decreasing template message size +- Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT +- Change commands ``SlaveSend`` and ``SlaveReset`` into ``ClientSend`` and ``ClientReset`` - Fix escape of non-JSON received serial data (#8329) - Add command ``Rule0`` to change global rule parameters - Add command ``Time 4`` to display timestamp using milliseconds (#8537) - Add command ``SetOption94 0/1`` to select MAX31855 or MAX6675 thermocouple support (#8616) +- Add command ``Module2`` to configure fallback module on fast reboot (#8464) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) - Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3`` - Add support for unique MQTTClient (and inherited fallback topic) by full Mac address using ``mqttclient DVES_%12X`` (#8300) @@ -80,6 +84,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add initial support for Telegram bot (#8619) - Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638) - Add rule trigger ``System#Init`` to allow early rule execution without wifi and mqtt initialized yet -- Created Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff -- Added Library to be used for decoding Teleinfo (French Metering Smart Meter) +- Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff +- Add Library to be used for decoding Teleinfo (French Metering Smart Meter) - Add basic support for ESP32 ethernet adding commands ``Wifi 0/1`` and ``Ethernet 0/1`` both default ON +- Add support for single wire LMT01 temperature Sensor by justifiably (#8713) diff --git a/lib/esp-knx-ip-0.5.2/esp-knx-ip.h b/lib/esp-knx-ip-0.5.2/esp-knx-ip.h index ea711825f..7150706bb 100644 --- a/lib/esp-knx-ip-0.5.2/esp-knx-ip.h +++ b/lib/esp-knx-ip-0.5.2/esp-knx-ip.h @@ -398,7 +398,7 @@ typedef struct __callback_assignment } callback_assignment_t; // FastPrecisePowf from tasmota/support_float.ino -extern float FastPrecisePowf(const float x, const float y); +//extern float FastPrecisePowf(const float x, const float y); class ESPKNXIP { public: @@ -567,7 +567,7 @@ class ESPKNXIP { callback_assignment_id_t __callback_register_assignment(address_t address, callback_id_t id); void __callback_delete_assignment(callback_assignment_id_t id); - static inline float pow(float a, float b) { return FastPrecisePowf(a, b); } + //static inline float pow(float a, float b) { return FastPrecisePowf(a, b); } ESP8266WebServer *server; address_t physaddr; diff --git a/lib/mbedtls/README.md b/lib/mbedtls/README.md new file mode 100644 index 000000000..f5df7f0c8 --- /dev/null +++ b/lib/mbedtls/README.md @@ -0,0 +1 @@ +Stripped down library for aes-ccm-decryption in the MI_NRF24.ino. \ No newline at end of file diff --git a/lib/mbedtls/include/mbedtls/aes.h b/lib/mbedtls/include/mbedtls/aes.h new file mode 100644 index 000000000..a36e825a2 --- /dev/null +++ b/lib/mbedtls/include/mbedtls/aes.h @@ -0,0 +1,297 @@ +/** + * \file aes.h + * + * \brief AES block cipher + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_AES_H +#define MBEDTLS_AES_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include +#include + +/* padlock.c and aesni.c rely on these values! */ +#define MBEDTLS_AES_ENCRYPT 1 +#define MBEDTLS_AES_DECRYPT 0 + +#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */ +#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */ + +#if !defined(MBEDTLS_AES_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief AES context structure + * + * \note buf is able to hold 32 extra bytes, which can be used: + * - for alignment purposes if VIA padlock is used, and/or + * - to simplify key expansion in the 256-bit case by + * generating an extra round key + */ +typedef struct +{ + int nr; /*!< number of rounds */ + uint32_t *rk; /*!< AES round keys */ + uint32_t buf[68]; /*!< unaligned data */ +} +mbedtls_aes_context; + +/** + * \brief Initialize AES context + * + * \param ctx AES context to be initialized + */ +void mbedtls_aes_init( mbedtls_aes_context *ctx ); + +/** + * \brief Clear AES context + * + * \param ctx AES context to be cleared + */ +void mbedtls_aes_free( mbedtls_aes_context *ctx ); + +/** + * \brief AES key schedule (encryption) + * + * \param ctx AES context to be initialized + * \param key encryption key + * \param keybits must be 128, 192 or 256 + * + * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH + */ +int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ); + +/** + * \brief AES key schedule (decryption) + * + * \param ctx AES context to be initialized + * \param key decryption key + * \param keybits must be 128, 192 or 256 + * + * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH + */ +int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ); + +/** + * \brief AES-ECB block encryption/decryption + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/** + * \brief AES-CBC buffer encryption/decryption + * Length should be a multiple of the block + * size (16 bytes) + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH + */ +int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/** + * \brief AES-CFB128 buffer encryption/decryption. + * + * Note: Due to the nature of CFB you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param length length of the input data + * \param iv_off offset in IV (updated after use) + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +/** + * \brief AES-CFB8 buffer encryption/decryption. + * + * Note: Due to the nature of CFB you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); +#endif /*MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/** + * \brief AES-CTR buffer encryption/decryption + * + * Warning: You have to keep the maximum use of your counter in mind! + * + * Note: Due to the nature of CTR you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * mbedtls_aes_setkey_enc() for both MBEDTLS_AES_ENCRYPT and MBEDTLS_AES_DECRYPT. + * + * \param ctx AES context + * \param length The length of the data + * \param nc_off The offset in the current stream_block (for resuming + * within current cipher stream). The offset pointer to + * should be 0 at the start of a stream. + * \param nonce_counter The 128-bit nonce and counter. + * \param stream_block The saved stream-block for resuming. Is overwritten + * by the function. + * \param input The input data stream + * \param output The output data stream + * + * \return 0 if successful + */ +int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ); +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +/** + * \brief Internal AES block encryption function + * (Only exposed to allow overriding it, + * see MBEDTLS_AES_ENCRYPT_ALT) + * + * \param ctx AES context + * \param input Plaintext block + * \param output Output (ciphertext) block + */ +void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +/** + * \brief Internal AES block decryption function + * (Only exposed to allow overriding it, + * see MBEDTLS_AES_DECRYPT_ALT) + * + * \param ctx AES context + * \param input Ciphertext block + * \param output Output (plaintext) block + */ +void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_AES_ALT */ +#include "aes_alt.h" +#endif /* MBEDTLS_AES_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mbedtls_aes_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* aes.h */ diff --git a/lib/mbedtls/include/mbedtls/ccm.h b/lib/mbedtls/include/mbedtls/ccm.h new file mode 100644 index 000000000..ef75839ba --- /dev/null +++ b/lib/mbedtls/include/mbedtls/ccm.h @@ -0,0 +1,141 @@ +/** + * \file ccm.h + * + * \brief Counter with CBC-MAC (CCM) for 128-bit block ciphers + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_CCM_H +#define MBEDTLS_CCM_H + +#include "cipher.h" + +#define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to function. */ +#define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief CCM context structure + */ +typedef struct { + mbedtls_cipher_context_t cipher_ctx; /*!< cipher context used */ +} +mbedtls_ccm_context; + +/** + * \brief Initialize CCM context (just makes references valid) + * Makes the context ready for mbedtls_ccm_setkey() or + * mbedtls_ccm_free(). + * + * \param ctx CCM context to initialize + */ +void mbedtls_ccm_init( mbedtls_ccm_context *ctx ); + +/** + * \brief CCM initialization (encryption and decryption) + * + * \param ctx CCM context to be initialized + * \param cipher cipher to use (a 128-bit block cipher) + * \param key encryption key + * \param keybits key size in bits (must be acceptable by the cipher) + * + * \return 0 if successful, or a cipher specific error code + */ +int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits ); + +/** + * \brief Free a CCM context and underlying cipher sub-context + * + * \param ctx CCM context to free + */ +void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); + +/** + * \brief CCM buffer encryption + * + * \param ctx CCM context + * \param length length of the input data in bytes + * \param iv nonce (initialization vector) + * \param iv_len length of IV in bytes + * must be 2, 3, 4, 5, 6, 7 or 8 + * \param add additional data + * \param add_len length of additional data in bytes + * must be less than 2^16 - 2^8 + * \param input buffer holding the input data + * \param output buffer for holding the output data + * must be at least 'length' bytes wide + * \param tag buffer for holding the tag + * \param tag_len length of the tag to generate in bytes + * must be 4, 6, 8, 10, 14 or 16 + * + * \note The tag is written to a separate buffer. To get the tag + * concatenated with the output as in the CCM spec, use + * tag = output + length and make sure the output buffer is + * at least length + tag_len wide. + * + * \return 0 if successful + */ +int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ); + +/** + * \brief CCM buffer authenticated decryption + * + * \param ctx CCM context + * \param length length of the input data + * \param iv initialization vector + * \param iv_len length of IV + * \param add additional data + * \param add_len length of additional data + * \param input buffer holding the input data + * \param output buffer for holding the output data + * \param tag buffer holding the tag + * \param tag_len length of the tag + * + * \return 0 if successful and authenticated, + * MBEDTLS_ERR_CCM_AUTH_FAILED if tag does not match + */ +int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len ); + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mbedtls_ccm_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CCM_H */ diff --git a/lib/mbedtls/include/mbedtls/check_config.h b/lib/mbedtls/include/mbedtls/check_config.h new file mode 100644 index 000000000..fe86c1e8d --- /dev/null +++ b/lib/mbedtls/include/mbedtls/check_config.h @@ -0,0 +1,628 @@ +/** + * \file check_config.h + * + * \brief Consistency checks for configuration options + * + * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * It is recommended to include this file from your config.h + * in order to catch dependency issues early. + */ + +#ifndef MBEDTLS_CHECK_CONFIG_H +#define MBEDTLS_CHECK_CONFIG_H + +/* + * We assume CHAR_BIT is 8 in many places. In practice, this is true on our + * target platforms, so not an issue, but let's just be extra sure. + */ +#include +#if CHAR_BIT != 8 +#error "mbed TLS requires a platform with 8-bit chars" +#endif + +#if defined(_WIN32) +#if !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_C is required on Windows" +#endif + +/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as + * it would confuse config.pl. */ +#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \ + !defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) +#define MBEDTLS_PLATFORM_SNPRINTF_ALT +#endif +#endif /* _WIN32 */ + +#if defined(TARGET_LIKE_MBED) && \ + ( defined(MBEDTLS_NET_C) || defined(MBEDTLS_TIMING_C) ) +#error "The NET and TIMING modules are not available for mbed OS - please use the network and timing functions provided by mbed OS" +#endif + +#if defined(MBEDTLS_DEPRECATED_WARNING) && \ + !defined(__GNUC__) && !defined(__clang__) +#error "MBEDTLS_DEPRECATED_WARNING only works with GCC and Clang" +#endif + +#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_HAVE_TIME) +#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense" +#endif + +#if defined(MBEDTLS_AESNI_C) && !defined(MBEDTLS_HAVE_ASM) +#error "MBEDTLS_AESNI_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C) +#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C) +#error "MBEDTLS_DHM_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_CMAC_C) && \ + !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C) +#error "MBEDTLS_CMAC_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C) +#error "MBEDTLS_ECDH_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECDSA_C) && \ + ( !defined(MBEDTLS_ECP_C) || \ + !defined(MBEDTLS_ASN1_PARSE_C) || \ + !defined(MBEDTLS_ASN1_WRITE_C) ) +#error "MBEDTLS_ECDSA_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECJPAKE_C) && \ + ( !defined(MBEDTLS_ECP_C) || !defined(MBEDTLS_MD_C) ) +#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C) +#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \ + !defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) ) ) +#error "MBEDTLS_ECP_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ENTROPY_C) && (!defined(MBEDTLS_SHA512_C) && \ + !defined(MBEDTLS_SHA256_C)) +#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites" +#endif +#if defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_SHA512_C) && \ + defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 64) +#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" +#endif +#if defined(MBEDTLS_ENTROPY_C) && \ + ( !defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_ENTROPY_FORCE_SHA256) ) \ + && defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 32) +#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" +#endif +#if defined(MBEDTLS_ENTROPY_C) && \ + defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_SHA256_C) +#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \ + ( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) ) +#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites" +#endif +#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \ + ( defined(MBEDTLS_ENTROPY_NV_SEED) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \ + defined(MBEDTLS_HAVEGE_C) ) +#error "MBEDTLS_TEST_NULL_ENTROPY defined, but entropy sources too" +#endif + +#if defined(MBEDTLS_GCM_C) && ( \ + !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) ) +#error "MBEDTLS_GCM_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C) +#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C) +#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \ + ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) ) +#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) ) +#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(MBEDTLS_DHM_C) +#error "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \ + !defined(MBEDTLS_ECDH_C) +#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + ( !defined(MBEDTLS_DHM_C) || !defined(MBEDTLS_RSA_C) || \ + !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \ + !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ + ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \ + !defined(MBEDTLS_X509_CRT_PARSE_C) ) +#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ + ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ + !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ + ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ + !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ + ( !defined(MBEDTLS_ECJPAKE_C) || !defined(MBEDTLS_SHA256_C) || \ + !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) ) +#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) +#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM) +#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C) +#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PEM_WRITE_C) && !defined(MBEDTLS_BASE64_C) +#error "MBEDTLS_PEM_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PK_C) && \ + ( !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_ECP_C) ) +#error "MBEDTLS_PK_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_PK_C) +#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PK_WRITE_C) && !defined(MBEDTLS_PK_C) +#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PKCS11_C) && !defined(MBEDTLS_PK_C) +#error "MBEDTLS_PKCS11_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_EXIT_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_EXIT) ||\ + defined(MBEDTLS_PLATFORM_EXIT_ALT) ) +#error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_ALT) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ + defined(MBEDTLS_PLATFORM_TIME_ALT) ) +#error "MBEDTLS_PLATFORM_TIME_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ + defined(MBEDTLS_PLATFORM_TIME_ALT) ) +#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_FPRINTF_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_FPRINTF) ||\ + defined(MBEDTLS_PLATFORM_FPRINTF_ALT) ) +#error "MBEDTLS_PLATFORM_FPRINTF_MACRO and MBEDTLS_PLATFORM_STD_FPRINTF/MBEDTLS_PLATFORM_FPRINTF_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) +#error "MBEDTLS_PLATFORM_FREE_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ + defined(MBEDTLS_PLATFORM_STD_FREE) +#error "MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_STD_FREE cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && !defined(MBEDTLS_PLATFORM_CALLOC_MACRO) +#error "MBEDTLS_PLATFORM_CALLOC_MACRO must be defined if MBEDTLS_PLATFORM_FREE_MACRO is" +#endif + +#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) +#error "MBEDTLS_PLATFORM_CALLOC_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ + defined(MBEDTLS_PLATFORM_STD_CALLOC) +#error "MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_STD_CALLOC cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && !defined(MBEDTLS_PLATFORM_FREE_MACRO) +#error "MBEDTLS_PLATFORM_FREE_MACRO must be defined if MBEDTLS_PLATFORM_CALLOC_MACRO is" +#endif + +#if defined(MBEDTLS_PLATFORM_MEMORY) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_MEMORY defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_PRINTF_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_PRINTF_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_PRINTF) ||\ + defined(MBEDTLS_PLATFORM_PRINTF_ALT) ) +#error "MBEDTLS_PLATFORM_PRINTF_MACRO and MBEDTLS_PLATFORM_STD_PRINTF/MBEDTLS_PLATFORM_PRINTF_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_SNPRINTF_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_SNPRINTF) ||\ + defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) ) +#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) &&\ + !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) +#error "MBEDTLS_PLATFORM_STD_MEM_HDR defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY) +#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY) +#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_FREE) && !defined(MBEDTLS_PLATFORM_MEMORY) +#error "MBEDTLS_PLATFORM_STD_FREE defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_EXIT) &&\ + !defined(MBEDTLS_PLATFORM_EXIT_ALT) +#error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_TIME) &&\ + ( !defined(MBEDTLS_PLATFORM_TIME_ALT) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_STD_TIME defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\ + !defined(MBEDTLS_PLATFORM_FPRINTF_ALT) +#error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_PRINTF) &&\ + !defined(MBEDTLS_PLATFORM_PRINTF_ALT) +#error "MBEDTLS_PLATFORM_STD_PRINTF defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_SNPRINTF) &&\ + !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) +#error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ENTROPY_NV_SEED) &&\ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_ENTROPY_C) ) +#error "MBEDTLS_ENTROPY_NV_SEED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) &&\ + !defined(MBEDTLS_ENTROPY_NV_SEED) +#error "MBEDTLS_PLATFORM_NV_SEED_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) &&\ + !defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +#error "MBEDTLS_PLATFORM_STD_NV_SEED_READ defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) &&\ + !defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +#error "MBEDTLS_PLATFORM_STD_NV_SEED_WRITE defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) ||\ + defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) +#error "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_READ cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) ||\ + defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) +#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ + !defined(MBEDTLS_OID_C) ) +#error "MBEDTLS_RSA_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_PKCS1_V21) && \ + !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_RSA_C defined, but none of the PKCS1 versions enabled" +#endif + +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \ + ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) ) +#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) || \ + !defined(MBEDTLS_SHA1_C) ) +#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1) && ( !defined(MBEDTLS_MD5_C) || \ + !defined(MBEDTLS_SHA1_C) ) +#error "MBEDTLS_SSL_PROTO_TLS1 defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1_1) && ( !defined(MBEDTLS_MD5_C) || \ + !defined(MBEDTLS_SHA1_C) ) +#error "MBEDTLS_SSL_PROTO_TLS1_1 defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && ( !defined(MBEDTLS_SHA1_C) && \ + !defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) ) +#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_PROTO_DTLS) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_2) +#error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_TLS_C) +#error "MBEDTLS_SSL_CLI_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) && ( !defined(MBEDTLS_CIPHER_C) || \ + !defined(MBEDTLS_MD_C) ) +#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_TLS_C) +#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) && (!defined(MBEDTLS_SSL_PROTO_SSL3) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1) && !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_2)) +#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) && !defined(MBEDTLS_SSL_PROTO_TLS1)) +#error "Illegal protocol selection" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_TLS1) && \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) && !defined(MBEDTLS_SSL_PROTO_TLS1_1)) +#error "Illegal protocol selection" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) && (!defined(MBEDTLS_SSL_PROTO_TLS1) || \ + !defined(MBEDTLS_SSL_PROTO_TLS1_1))) +#error "Illegal protocol selection" +#endif + +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDTLS_SSL_PROTO_DTLS) +#error "MBEDTLS_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \ + !defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) +#error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ + ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) +#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \ + ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) +#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_2) +#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequsites" +#endif + +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_2) +#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequsites" +#endif + +#if defined(MBEDTLS_SSL_TICKET_C) && !defined(MBEDTLS_CIPHER_C) +#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) && \ + !defined(MBEDTLS_SSL_PROTO_SSL3) && !defined(MBEDTLS_SSL_PROTO_TLS1) +#error "MBEDTLS_SSL_CBC_RECORD_SPLITTING defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \ + !defined(MBEDTLS_X509_CRT_PARSE_C) +#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_THREADING_PTHREAD) +#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) +#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites" +#endif +#define MBEDTLS_THREADING_IMPL +#endif + +#if defined(MBEDTLS_THREADING_ALT) +#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) +#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites" +#endif +#define MBEDTLS_THREADING_IMPL +#endif + +#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL) +#error "MBEDTLS_THREADING_C defined, single threading implementation required" +#endif +#undef MBEDTLS_THREADING_IMPL + +#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C) +#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_USE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ + !defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \ + !defined(MBEDTLS_PK_PARSE_C) ) +#error "MBEDTLS_X509_USE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CREATE_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ + !defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \ + !defined(MBEDTLS_PK_WRITE_C) ) +#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) +#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CRL_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) +#error "MBEDTLS_X509_CRL_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CSR_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) +#error "MBEDTLS_X509_CSR_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CRT_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) +#error "MBEDTLS_X509_CRT_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CSR_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) +#error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites" +#endif + +/* + * Avoid warning from -pedantic. This is a convenient place for this + * workaround since this is included by every single file before the + * #if defined(MBEDTLS_xxx_C) that results in emtpy translation units. + */ +typedef int mbedtls_iso_c_forbids_empty_translation_units; + +#endif /* MBEDTLS_CHECK_CONFIG_H */ diff --git a/lib/mbedtls/include/mbedtls/cipher.h b/lib/mbedtls/include/mbedtls/cipher.h new file mode 100644 index 000000000..b12e38843 --- /dev/null +++ b/lib/mbedtls/include/mbedtls/cipher.h @@ -0,0 +1,709 @@ +/** + * \file cipher.h + * + * \brief Generic cipher wrapper. + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#ifndef MBEDTLS_CIPHER_H +#define MBEDTLS_CIPHER_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) +#define MBEDTLS_CIPHER_MODE_AEAD +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#define MBEDTLS_CIPHER_MODE_WITH_PADDING +#endif + +#if defined(MBEDTLS_ARC4_C) +#define MBEDTLS_CIPHER_MODE_STREAM +#endif + +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + +#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */ +#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters to function. */ +#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */ +#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */ +#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */ +#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */ +#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid, eg because it was free()ed. */ + +#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length */ +#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + MBEDTLS_CIPHER_ID_NONE = 0, + MBEDTLS_CIPHER_ID_NULL, + MBEDTLS_CIPHER_ID_AES, + MBEDTLS_CIPHER_ID_DES, + MBEDTLS_CIPHER_ID_3DES, + MBEDTLS_CIPHER_ID_CAMELLIA, + MBEDTLS_CIPHER_ID_BLOWFISH, + MBEDTLS_CIPHER_ID_ARC4, +} mbedtls_cipher_id_t; + +typedef enum { + MBEDTLS_CIPHER_NONE = 0, + MBEDTLS_CIPHER_NULL, + MBEDTLS_CIPHER_AES_128_ECB, + MBEDTLS_CIPHER_AES_192_ECB, + MBEDTLS_CIPHER_AES_256_ECB, + MBEDTLS_CIPHER_AES_128_CBC, + MBEDTLS_CIPHER_AES_192_CBC, + MBEDTLS_CIPHER_AES_256_CBC, + MBEDTLS_CIPHER_AES_128_CFB128, + MBEDTLS_CIPHER_AES_192_CFB128, + MBEDTLS_CIPHER_AES_256_CFB128, + MBEDTLS_CIPHER_AES_128_CTR, + MBEDTLS_CIPHER_AES_192_CTR, + MBEDTLS_CIPHER_AES_256_CTR, + MBEDTLS_CIPHER_AES_128_GCM, + MBEDTLS_CIPHER_AES_192_GCM, + MBEDTLS_CIPHER_AES_256_GCM, + MBEDTLS_CIPHER_CAMELLIA_128_ECB, + MBEDTLS_CIPHER_CAMELLIA_192_ECB, + MBEDTLS_CIPHER_CAMELLIA_256_ECB, + MBEDTLS_CIPHER_CAMELLIA_128_CBC, + MBEDTLS_CIPHER_CAMELLIA_192_CBC, + MBEDTLS_CIPHER_CAMELLIA_256_CBC, + MBEDTLS_CIPHER_CAMELLIA_128_CFB128, + MBEDTLS_CIPHER_CAMELLIA_192_CFB128, + MBEDTLS_CIPHER_CAMELLIA_256_CFB128, + MBEDTLS_CIPHER_CAMELLIA_128_CTR, + MBEDTLS_CIPHER_CAMELLIA_192_CTR, + MBEDTLS_CIPHER_CAMELLIA_256_CTR, + MBEDTLS_CIPHER_CAMELLIA_128_GCM, + MBEDTLS_CIPHER_CAMELLIA_192_GCM, + MBEDTLS_CIPHER_CAMELLIA_256_GCM, + MBEDTLS_CIPHER_DES_ECB, + MBEDTLS_CIPHER_DES_CBC, + MBEDTLS_CIPHER_DES_EDE_ECB, + MBEDTLS_CIPHER_DES_EDE_CBC, + MBEDTLS_CIPHER_DES_EDE3_ECB, + MBEDTLS_CIPHER_DES_EDE3_CBC, + MBEDTLS_CIPHER_BLOWFISH_ECB, + MBEDTLS_CIPHER_BLOWFISH_CBC, + MBEDTLS_CIPHER_BLOWFISH_CFB64, + MBEDTLS_CIPHER_BLOWFISH_CTR, + MBEDTLS_CIPHER_ARC4_128, + MBEDTLS_CIPHER_AES_128_CCM, + MBEDTLS_CIPHER_AES_192_CCM, + MBEDTLS_CIPHER_AES_256_CCM, + MBEDTLS_CIPHER_CAMELLIA_128_CCM, + MBEDTLS_CIPHER_CAMELLIA_192_CCM, + MBEDTLS_CIPHER_CAMELLIA_256_CCM, +} mbedtls_cipher_type_t; + +typedef enum { + MBEDTLS_MODE_NONE = 0, + MBEDTLS_MODE_ECB, + MBEDTLS_MODE_CBC, + MBEDTLS_MODE_CFB, + MBEDTLS_MODE_OFB, /* Unused! */ + MBEDTLS_MODE_CTR, + MBEDTLS_MODE_GCM, + MBEDTLS_MODE_STREAM, + MBEDTLS_MODE_CCM, +} mbedtls_cipher_mode_t; + +typedef enum { + MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default) */ + MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding */ + MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding */ + MBEDTLS_PADDING_ZEROS, /**< zero padding (not reversible!) */ + MBEDTLS_PADDING_NONE, /**< never pad (full blocks only) */ +} mbedtls_cipher_padding_t; + +typedef enum { + MBEDTLS_OPERATION_NONE = -1, + MBEDTLS_DECRYPT = 0, + MBEDTLS_ENCRYPT, +} mbedtls_operation_t; + +enum { + /** Undefined key length */ + MBEDTLS_KEY_LENGTH_NONE = 0, + /** Key length, in bits (including parity), for DES keys */ + MBEDTLS_KEY_LENGTH_DES = 64, + /** Key length, in bits (including parity), for DES in two key EDE */ + MBEDTLS_KEY_LENGTH_DES_EDE = 128, + /** Key length, in bits (including parity), for DES in three-key EDE */ + MBEDTLS_KEY_LENGTH_DES_EDE3 = 192, +}; + +/** Maximum length of any IV, in bytes */ +#define MBEDTLS_MAX_IV_LENGTH 16 +/** Maximum block size of any cipher, in bytes */ +#define MBEDTLS_MAX_BLOCK_LENGTH 16 + +/** + * Base cipher information (opaque struct). + */ +typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t; + +/** + * CMAC context (opaque struct). + */ +typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t; + +/** + * Cipher information. Allows cipher functions to be called in a generic way. + */ +typedef struct { + /** Full cipher identifier (e.g. MBEDTLS_CIPHER_AES_256_CBC) */ + mbedtls_cipher_type_t type; + + /** Cipher mode (e.g. MBEDTLS_MODE_CBC) */ + mbedtls_cipher_mode_t mode; + + /** Cipher key length, in bits (default length for variable sized ciphers) + * (Includes parity bits for ciphers like DES) */ + unsigned int key_bitlen; + + /** Name of the cipher */ + const char * name; + + /** IV/NONCE size, in bytes. + * For cipher that accept many sizes: recommended size */ + unsigned int iv_size; + + /** Flags for variable IV size, variable key size, etc. */ + int flags; + + /** block size, in bytes */ + unsigned int block_size; + + /** Base cipher information and functions */ + const mbedtls_cipher_base_t *base; + +} mbedtls_cipher_info_t; + +/** + * Generic cipher context. + */ +typedef struct { + /** Information about the associated cipher */ + const mbedtls_cipher_info_t *cipher_info; + + /** Key length to use */ + int key_bitlen; + + /** Operation that the context's key has been initialised for */ + mbedtls_operation_t operation; + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) + /** Padding functions to use, if relevant for cipher mode */ + void (*add_padding)( unsigned char *output, size_t olen, size_t data_len ); + int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len ); +#endif + + /** Buffer for data that hasn't been encrypted yet */ + unsigned char unprocessed_data[MBEDTLS_MAX_BLOCK_LENGTH]; + + /** Number of bytes that still need processing */ + size_t unprocessed_len; + + /** Current IV or NONCE_COUNTER for CTR-mode */ + unsigned char iv[MBEDTLS_MAX_IV_LENGTH]; + + /** IV size in bytes (for ciphers with variable-length IVs) */ + size_t iv_size; + + /** Cipher-specific context */ + void *cipher_ctx; + +#if defined(MBEDTLS_CMAC_C) + /** CMAC Specific context */ + mbedtls_cmac_context_t *cmac_ctx; +#endif +} mbedtls_cipher_context_t; + +/** + * \brief Returns the list of ciphers supported by the generic cipher module. + * + * \return a statically allocated array of ciphers, the last entry + * is 0. + */ +const int *mbedtls_cipher_list( void ); + +/** + * \brief Returns the cipher information structure associated + * with the given cipher name. + * + * \param cipher_name Name of the cipher to search for. + * + * \return the cipher information structure associated with the + * given cipher_name, or NULL if not found. + */ +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ); + +/** + * \brief Returns the cipher information structure associated + * with the given cipher type. + * + * \param cipher_type Type of the cipher to search for. + * + * \return the cipher information structure associated with the + * given cipher_type, or NULL if not found. + */ +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ); + +/** + * \brief Returns the cipher information structure associated + * with the given cipher id, key size and mode. + * + * \param cipher_id Id of the cipher to search for + * (e.g. MBEDTLS_CIPHER_ID_AES) + * \param key_bitlen Length of the key in bits + * \param mode Cipher mode (e.g. MBEDTLS_MODE_CBC) + * + * \return the cipher information structure associated with the + * given cipher_type, or NULL if not found. + */ +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, + int key_bitlen, + const mbedtls_cipher_mode_t mode ); + +/** + * \brief Initialize a cipher_context (as NONE) + */ +void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ); + +/** + * \brief Free and clear the cipher-specific context of ctx. + * Freeing ctx itself remains the responsibility of the + * caller. + */ +void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ); + +/** + * \brief Initialises and fills the cipher context structure with + * the appropriate values. + * + * \note Currently also clears structure. In future versions you + * will be required to call mbedtls_cipher_init() on the structure + * first. + * + * \param ctx context to initialise. May not be NULL. + * \param cipher_info cipher to use. + * + * \return 0 on success, + * MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on parameter failure, + * MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the + * cipher-specific context failed. + */ +int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info ); + +/** + * \brief Returns the block size of the given cipher. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return size of the cipher's blocks, or 0 if ctx has not been + * initialised. + */ +static inline unsigned int mbedtls_cipher_get_block_size( const mbedtls_cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return 0; + + return ctx->cipher_info->block_size; +} + +/** + * \brief Returns the mode of operation for the cipher. + * (e.g. MBEDTLS_MODE_CBC) + * + * \param ctx cipher's context. Must have been initialised. + * + * \return mode of operation, or MBEDTLS_MODE_NONE if ctx + * has not been initialised. + */ +static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( const mbedtls_cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return MBEDTLS_MODE_NONE; + + return ctx->cipher_info->mode; +} + +/** + * \brief Returns the size of the cipher's IV/NONCE in bytes. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return If IV has not been set yet: (recommended) IV size + * (0 for ciphers not using IV/NONCE). + * If IV has already been set: actual size. + */ +static inline int mbedtls_cipher_get_iv_size( const mbedtls_cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return 0; + + if( ctx->iv_size != 0 ) + return (int) ctx->iv_size; + + return (int) ctx->cipher_info->iv_size; +} + +/** + * \brief Returns the type of the given cipher. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return type of the cipher, or MBEDTLS_CIPHER_NONE if ctx has + * not been initialised. + */ +static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( const mbedtls_cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return MBEDTLS_CIPHER_NONE; + + return ctx->cipher_info->type; +} + +/** + * \brief Returns the name of the given cipher, as a string. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return name of the cipher, or NULL if ctx was not initialised. + */ +static inline const char *mbedtls_cipher_get_name( const mbedtls_cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return 0; + + return ctx->cipher_info->name; +} + +/** + * \brief Returns the key length of the cipher. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return cipher's key length, in bits, or + * MBEDTLS_KEY_LENGTH_NONE if ctx has not been + * initialised. + */ +static inline int mbedtls_cipher_get_key_bitlen( const mbedtls_cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return MBEDTLS_KEY_LENGTH_NONE; + + return (int) ctx->cipher_info->key_bitlen; +} + +/** + * \brief Returns the operation of the given cipher. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return operation (MBEDTLS_ENCRYPT or MBEDTLS_DECRYPT), + * or MBEDTLS_OPERATION_NONE if ctx has not been + * initialised. + */ +static inline mbedtls_operation_t mbedtls_cipher_get_operation( const mbedtls_cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return MBEDTLS_OPERATION_NONE; + + return ctx->operation; +} + +/** + * \brief Set the key to use with the given context. + * + * \param ctx generic cipher context. May not be NULL. Must have been + * initialised using cipher_context_from_type or + * cipher_context_from_string. + * \param key The key to use. + * \param key_bitlen key length to use, in bits. + * \param operation Operation that the key will be used for, either + * MBEDTLS_ENCRYPT or MBEDTLS_DECRYPT. + * + * \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if + * parameter verification fails or a cipher specific + * error code. + */ +int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key, + int key_bitlen, const mbedtls_operation_t operation ); + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) +/** + * \brief Set padding mode, for cipher modes that use padding. + * (Default: PKCS7 padding.) + * + * \param ctx generic cipher context + * \param mode padding mode + * + * \returns 0 on success, MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE + * if selected padding mode is not supported, or + * MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode + * does not support padding. + */ +int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode ); +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + +/** + * \brief Set the initialization vector (IV) or nonce + * + * \param ctx generic cipher context + * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) + * \param iv_len IV length for ciphers with variable-size IV; + * discarded by ciphers with fixed-size IV. + * + * \returns 0 on success, or MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA + * + * \note Some ciphers don't use IVs nor NONCE. For these + * ciphers, this function has no effect. + */ +int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len ); + +/** + * \brief Finish preparation of the given context + * + * \param ctx generic cipher context + * + * \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA + * if parameter verification fails. + */ +int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ); + +#if defined(MBEDTLS_GCM_C) +/** + * \brief Add additional data (for AEAD ciphers). + * Currently only supported with GCM. + * Must be called exactly once, after mbedtls_cipher_reset(). + * + * \param ctx generic cipher context + * \param ad Additional data to use. + * \param ad_len Length of ad. + * + * \return 0 on success, or a specific error code. + */ +int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, + const unsigned char *ad, size_t ad_len ); +#endif /* MBEDTLS_GCM_C */ + +/** + * \brief Generic cipher update function. Encrypts/decrypts + * using the given cipher context. Writes as many block + * size'd blocks of data as possible to output. Any data + * that cannot be written immediately will either be added + * to the next block, or flushed when cipher_final is + * called. + * Exception: for MBEDTLS_MODE_ECB, expects single block + * in size (e.g. 16 bytes for AES) + * + * \param ctx generic cipher context + * \param input buffer holding the input data + * \param ilen length of the input data + * \param output buffer for the output data. Should be able to hold at + * least ilen + block_size. Cannot be the same buffer as + * input! + * \param olen length of the output data, will be filled with the + * actual number of bytes written. + * + * \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if + * parameter verification fails, + * MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an + * unsupported mode for a cipher or a cipher specific + * error code. + * + * \note If the underlying cipher is GCM, all calls to this + * function, except the last one before mbedtls_cipher_finish(), + * must have ilen a multiple of the block size. + */ +int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, + size_t ilen, unsigned char *output, size_t *olen ); + +/** + * \brief Generic cipher finalisation function. If data still + * needs to be flushed from an incomplete block, data + * contained within it will be padded with the size of + * the last block, and written to the output buffer. + * + * \param ctx Generic cipher context + * \param output buffer to write data to. Needs block_size available. + * \param olen length of the data written to the output buffer. + * + * \returns 0 on success, MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if + * parameter verification fails, + * MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption + * expected a full block but was not provided one, + * MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding + * while decrypting or a cipher specific error code. + */ +int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, + unsigned char *output, size_t *olen ); + +#if defined(MBEDTLS_GCM_C) +/** + * \brief Write tag for AEAD ciphers. + * Currently only supported with GCM. + * Must be called after mbedtls_cipher_finish(). + * + * \param ctx Generic cipher context + * \param tag buffer to write the tag + * \param tag_len Length of the tag to write + * + * \return 0 on success, or a specific error code. + */ +int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, + unsigned char *tag, size_t tag_len ); + +/** + * \brief Check tag for AEAD ciphers. + * Currently only supported with GCM. + * Must be called after mbedtls_cipher_finish(). + * + * \param ctx Generic cipher context + * \param tag Buffer holding the tag + * \param tag_len Length of the tag to check + * + * \return 0 on success, or a specific error code. + */ +int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, + const unsigned char *tag, size_t tag_len ); +#endif /* MBEDTLS_GCM_C */ + +/** + * \brief Generic all-in-one encryption/decryption + * (for all ciphers except AEAD constructs). + * + * \param ctx generic cipher context + * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) + * \param iv_len IV length for ciphers with variable-size IV; + * discarded by ciphers with fixed-size IV. + * \param input buffer holding the input data + * \param ilen length of the input data + * \param output buffer for the output data. Should be able to hold at + * least ilen + block_size. Cannot be the same buffer as + * input! + * \param olen length of the output data, will be filled with the + * actual number of bytes written. + * + * \note Some ciphers don't use IVs nor NONCE. For these + * ciphers, use iv = NULL and iv_len = 0. + * + * \returns 0 on success, or + * MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or + * MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption + * expected a full block but was not provided one, or + * MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding + * while decrypting, or + * a cipher specific error code. + */ +int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen ); + +#if defined(MBEDTLS_CIPHER_MODE_AEAD) +/** + * \brief Generic autenticated encryption (AEAD ciphers). + * + * \param ctx generic cipher context + * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) + * \param iv_len IV length for ciphers with variable-size IV; + * discarded by ciphers with fixed-size IV. + * \param ad Additional data to authenticate. + * \param ad_len Length of ad. + * \param input buffer holding the input data + * \param ilen length of the input data + * \param output buffer for the output data. + * Should be able to hold at least ilen. + * \param olen length of the output data, will be filled with the + * actual number of bytes written. + * \param tag buffer for the authentication tag + * \param tag_len desired tag length + * + * \returns 0 on success, or + * MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or + * a cipher specific error code. + */ +int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + unsigned char *tag, size_t tag_len ); + +/** + * \brief Generic autenticated decryption (AEAD ciphers). + * + * \param ctx generic cipher context + * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) + * \param iv_len IV length for ciphers with variable-size IV; + * discarded by ciphers with fixed-size IV. + * \param ad Additional data to be authenticated. + * \param ad_len Length of ad. + * \param input buffer holding the input data + * \param ilen length of the input data + * \param output buffer for the output data. + * Should be able to hold at least ilen. + * \param olen length of the output data, will be filled with the + * actual number of bytes written. + * \param tag buffer holding the authentication tag + * \param tag_len length of the authentication tag + * + * \returns 0 on success, or + * MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, or + * MBEDTLS_ERR_CIPHER_AUTH_FAILED if data isn't authentic, + * or a cipher specific error code. + * + * \note If the data is not authentic, then the output buffer + * is zeroed out to prevent the unauthentic plaintext to + * be used by mistake, making this interface safer. + */ +int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + const unsigned char *tag, size_t tag_len ); +#endif /* MBEDTLS_CIPHER_MODE_AEAD */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CIPHER_H */ diff --git a/lib/mbedtls/include/mbedtls/cipher_internal.h b/lib/mbedtls/include/mbedtls/cipher_internal.h new file mode 100644 index 000000000..6c58bcc52 --- /dev/null +++ b/lib/mbedtls/include/mbedtls/cipher_internal.h @@ -0,0 +1,109 @@ +/** + * \file cipher_internal.h + * + * \brief Cipher wrappers. + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_CIPHER_WRAP_H +#define MBEDTLS_CIPHER_WRAP_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "cipher.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Base cipher information. The non-mode specific functions and values. + */ +struct mbedtls_cipher_base_t +{ + /** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */ + mbedtls_cipher_id_t cipher; + + /** Encrypt using ECB */ + int (*ecb_func)( void *ctx, mbedtls_operation_t mode, + const unsigned char *input, unsigned char *output ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + /** Encrypt using CBC */ + int (*cbc_func)( void *ctx, mbedtls_operation_t mode, size_t length, + unsigned char *iv, const unsigned char *input, + unsigned char *output ); +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CFB) + /** Encrypt using CFB (Full length) */ + int (*cfb_func)( void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off, + unsigned char *iv, const unsigned char *input, + unsigned char *output ); +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CTR) + /** Encrypt using CTR */ + int (*ctr_func)( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ); +#endif + +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + /** Encrypt using STREAM */ + int (*stream_func)( void *ctx, size_t length, + const unsigned char *input, unsigned char *output ); +#endif + + /** Set key for encryption purposes */ + int (*setkey_enc_func)( void *ctx, const unsigned char *key, + unsigned int key_bitlen ); + + /** Set key for decryption purposes */ + int (*setkey_dec_func)( void *ctx, const unsigned char *key, + unsigned int key_bitlen); + + /** Allocate a new context */ + void * (*ctx_alloc_func)( void ); + + /** Free the given context */ + void (*ctx_free_func)( void *ctx ); + +}; + +typedef struct +{ + mbedtls_cipher_type_t type; + const mbedtls_cipher_info_t *info; +} mbedtls_cipher_definition_t; + +extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[]; + +extern int mbedtls_cipher_supported[]; + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CIPHER_WRAP_H */ diff --git a/lib/mbedtls/include/mbedtls/config.h b/lib/mbedtls/include/mbedtls/config.h new file mode 100644 index 000000000..0a3e1bb44 --- /dev/null +++ b/lib/mbedtls/include/mbedtls/config.h @@ -0,0 +1,2600 @@ +/** + * \file config.h + * + * \brief Configuration options (set of defines) + * + * This set of compile-time options may be used to enable + * or disable features selectively, and reduce the global + * memory footprint. + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#ifndef MBEDTLS_CONFIG_H +#define MBEDTLS_CONFIG_H + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + +/** + * \name SECTION: System support + * + * This section sets system specific settings. + * \{ + */ + +/** + * \def MBEDTLS_HAVE_ASM + * + * The compiler has support for asm(). + * + * Requires support for asm() in compiler. + * + * Used in: + * library/timing.c + * library/padlock.c + * include/mbedtls/bn_mul.h + * + * Comment to disable the use of assembly code. + */ +#define MBEDTLS_HAVE_ASM + +/** + * \def MBEDTLS_HAVE_SSE2 + * + * CPU supports SSE2 instruction set. + * + * Uncomment if the CPU supports SSE2 (IA-32 specific). + */ +//#define MBEDTLS_HAVE_SSE2 + +/** + * \def MBEDTLS_HAVE_TIME + * + * System has time.h and time(). + * The time does not need to be correct, only time differences are used, + * by contrast with MBEDTLS_HAVE_TIME_DATE + * + * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT, + * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and + * MBEDTLS_PLATFORM_STD_TIME. + * + * Comment if your system does not support time functions + */ +// #define MBEDTLS_HAVE_TIME + +/** + * \def MBEDTLS_HAVE_TIME_DATE + * + * System has time.h and time(), gmtime() and the clock is correct. + * The time needs to be correct (not necesarily very accurate, but at least + * the date should be correct). This is used to verify the validity period of + * X.509 certificates. + * + * Comment if your system does not have a correct clock. + */ +// #define MBEDTLS_HAVE_TIME_DATE + +/** + * \def MBEDTLS_PLATFORM_MEMORY + * + * Enable the memory allocation layer. + * + * By default mbed TLS uses the system-provided calloc() and free(). + * This allows different allocators (self-implemented or provided) to be + * provided to the platform abstraction layer. + * + * Enabling MBEDTLS_PLATFORM_MEMORY without the + * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide + * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and + * free() function pointer at runtime. + * + * Enabling MBEDTLS_PLATFORM_MEMORY and specifying + * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the + * alternate function at compile time. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Enable this layer to allow use of alternative memory allocators. + */ +//#define MBEDTLS_PLATFORM_MEMORY + +/** + * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + * + * Do not assign standard functions in the platform layer (e.g. calloc() to + * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF) + * + * This makes sure there are no linking errors on platforms that do not support + * these functions. You will HAVE to provide alternatives, either at runtime + * via the platform_set_xxx() functions or at compile time by setting + * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a + * MBEDTLS_PLATFORM_XXX_MACRO. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Uncomment to prevent default assignment of standard functions in the + * platform layer. + */ +//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + +/** + * \def MBEDTLS_PLATFORM_EXIT_ALT + * + * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the + * function in the platform abstraction layer. + * + * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will + * provide a function "mbedtls_platform_set_printf()" that allows you to set an + * alternative printf function pointer. + * + * All these define require MBEDTLS_PLATFORM_C to be defined! + * + * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows; + * it will be enabled automatically by check_config.h + * + * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as + * MBEDTLS_PLATFORM_XXX_MACRO! + * + * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME + * + * Uncomment a macro to enable alternate implementation of specific base + * platform function + */ +//#define MBEDTLS_PLATFORM_EXIT_ALT +//#define MBEDTLS_PLATFORM_TIME_ALT +//#define MBEDTLS_PLATFORM_FPRINTF_ALT +//#define MBEDTLS_PLATFORM_PRINTF_ALT +//#define MBEDTLS_PLATFORM_SNPRINTF_ALT +//#define MBEDTLS_PLATFORM_NV_SEED_ALT + +/** + * \def MBEDTLS_DEPRECATED_WARNING + * + * Mark deprecated functions so that they generate a warning if used. + * Functions deprecated in one version will usually be removed in the next + * version. You can enable this to help you prepare the transition to a new + * major version by making sure your code is not using these functions. + * + * This only works with GCC and Clang. With other compilers, you may want to + * use MBEDTLS_DEPRECATED_REMOVED + * + * Uncomment to get warnings on using deprecated functions. + */ +//#define MBEDTLS_DEPRECATED_WARNING + +/** + * \def MBEDTLS_DEPRECATED_REMOVED + * + * Remove deprecated functions so that they generate an error if used. + * Functions deprecated in one version will usually be removed in the next + * version. You can enable this to help you prepare the transition to a new + * major version by making sure your code is not using these functions. + * + * Uncomment to get errors on using deprecated functions. + */ +//#define MBEDTLS_DEPRECATED_REMOVED + +/* \} name SECTION: System support */ + +/** + * \name SECTION: mbed TLS feature support + * + * This section sets support for features that are or are not needed + * within the modules that are enabled. + * \{ + */ + +/** + * \def MBEDTLS_TIMING_ALT + * + * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(), + * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() + * + * Only works if you have MBEDTLS_TIMING_C enabled. + * + * You will need to provide a header "timing_alt.h" and an implementation at + * compile time. + */ +//#define MBEDTLS_TIMING_ALT + +/** + * \def MBEDTLS_AES_ALT + * + * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your + * alternate core implementation of a symmetric crypto or hash module (e.g. + * platform specific assembly optimized implementations). Keep in mind that + * the function prototypes should remain the same. + * + * This replaces the whole module. If you only want to replace one of the + * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer + * provide the "struct mbedtls_aes_context" definition and omit the base function + * declarations and implementations. "aes_alt.h" will be included from + * "aes.h" to include the new function definitions. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * module. + */ +//#define MBEDTLS_AES_ALT +//#define MBEDTLS_ARC4_ALT +//#define MBEDTLS_BLOWFISH_ALT +//#define MBEDTLS_CAMELLIA_ALT +//#define MBEDTLS_DES_ALT +//#define MBEDTLS_XTEA_ALT +//#define MBEDTLS_MD2_ALT +//#define MBEDTLS_MD4_ALT +//#define MBEDTLS_MD5_ALT +//#define MBEDTLS_RIPEMD160_ALT +//#define MBEDTLS_SHA1_ALT +//#define MBEDTLS_SHA256_ALT +//#define MBEDTLS_SHA512_ALT + +/** + * \def MBEDTLS_MD2_PROCESS_ALT + * + * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you + * alternate core implementation of symmetric crypto or hash function. Keep in + * mind that function prototypes should remain the same. + * + * This replaces only one function. The header file from mbed TLS is still + * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will + * no longer provide the mbedtls_sha1_process() function, but it will still provide + * the other function (using your mbedtls_sha1_process() function) and the definition + * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible + * with this definition. + * + * Note: if you use the AES_xxx_ALT macros, then is is recommended to also set + * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES + * tables. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + */ +//#define MBEDTLS_MD2_PROCESS_ALT +//#define MBEDTLS_MD4_PROCESS_ALT +//#define MBEDTLS_MD5_PROCESS_ALT +//#define MBEDTLS_RIPEMD160_PROCESS_ALT +//#define MBEDTLS_SHA1_PROCESS_ALT +//#define MBEDTLS_SHA256_PROCESS_ALT +//#define MBEDTLS_SHA512_PROCESS_ALT +//#define MBEDTLS_DES_SETKEY_ALT +//#define MBEDTLS_DES_CRYPT_ECB_ALT +//#define MBEDTLS_DES3_CRYPT_ECB_ALT +//#define MBEDTLS_AES_SETKEY_ENC_ALT +//#define MBEDTLS_AES_SETKEY_DEC_ALT +//#define MBEDTLS_AES_ENCRYPT_ALT +//#define MBEDTLS_AES_DECRYPT_ALT + +/** + * \def MBEDTLS_TEST_NULL_ENTROPY + * + * Enables testing and use of mbed TLS without any configured entropy sources. + * This permits use of the library on platforms before an entropy source has + * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the + * MBEDTLS_ENTROPY_NV_SEED switches). + * + * WARNING! This switch MUST be disabled in production builds, and is suitable + * only for development. + * Enabling the switch negates any security provided by the library. + * + * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + */ +//#define MBEDTLS_TEST_NULL_ENTROPY + +/** + * \def MBEDTLS_ENTROPY_HARDWARE_ALT + * + * Uncomment this macro to let mbed TLS use your own implementation of a + * hardware entropy collector. + * + * Your function must be called \c mbedtls_hardware_poll(), have the same + * prototype as declared in entropy_poll.h, and accept NULL as first argument. + * + * Uncomment to use your own hardware entropy collector. + */ +//#define MBEDTLS_ENTROPY_HARDWARE_ALT + +/** + * \def MBEDTLS_AES_ROM_TABLES + * + * Store the AES tables in ROM. + * + * Uncomment this macro to store the AES tables in ROM. + */ +//#define MBEDTLS_AES_ROM_TABLES + +/** + * \def MBEDTLS_CAMELLIA_SMALL_MEMORY + * + * Use less ROM for the Camellia implementation (saves about 768 bytes). + * + * Uncomment this macro to use less memory for Camellia. + */ +//#define MBEDTLS_CAMELLIA_SMALL_MEMORY + +/** + * \def MBEDTLS_CIPHER_MODE_CBC + * + * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. + */ +// #define MBEDTLS_CIPHER_MODE_CBC + +/** + * \def MBEDTLS_CIPHER_MODE_CFB + * + * Enable Cipher Feedback mode (CFB) for symmetric ciphers. + */ +// #define MBEDTLS_CIPHER_MODE_CFB + +/** + * \def MBEDTLS_CIPHER_MODE_CTR + * + * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_CTR + +/** + * \def MBEDTLS_CIPHER_NULL_CIPHER + * + * Enable NULL cipher. + * Warning: Only do so when you know what you are doing. This allows for + * encryption or channels without any security! + * + * Requires MBEDTLS_ENABLE_WEAK_CIPHERSUITES as well to enable + * the following ciphersuites: + * MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_RSA_WITH_NULL_SHA256 + * MBEDTLS_TLS_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_RSA_WITH_NULL_MD5 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_PSK_WITH_NULL_SHA + * + * Uncomment this macro to enable the NULL cipher and ciphersuites + */ +//#define MBEDTLS_CIPHER_NULL_CIPHER + +/** + * \def MBEDTLS_CIPHER_PADDING_PKCS7 + * + * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for + * specific padding modes in the cipher layer with cipher modes that support + * padding (e.g. CBC) + * + * If you disable all padding modes, only full blocks can be used with CBC. + * + * Enable padding modes in the cipher layer. + */ +#define MBEDTLS_CIPHER_PADDING_PKCS7 +#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS +#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN +#define MBEDTLS_CIPHER_PADDING_ZEROS + +/** + * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES + * + * Enable weak ciphersuites in SSL / TLS. + * Warning: Only do so when you know what you are doing. This allows for + * channels with virtually no security at all! + * + * This enables the following ciphersuites: + * MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA + * + * Uncomment this macro to enable weak ciphersuites + */ +//#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES + +/** + * \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES + * + * Remove RC4 ciphersuites by default in SSL / TLS. + * This flag removes the ciphersuites based on RC4 from the default list as + * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to + * enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them + * explicitly. + * + * Uncomment this macro to remove RC4 ciphersuites by default. + */ +#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES + +/** + * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED + * + * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve + * module. By default all supported curves are enabled. + * + * Comment macros to disable the curve and functions for it + */ +// #define MBEDTLS_ECP_DP_SECP192R1_ENABLED +// #define MBEDTLS_ECP_DP_SECP224R1_ENABLED +// #define MBEDTLS_ECP_DP_SECP256R1_ENABLED +// #define MBEDTLS_ECP_DP_SECP384R1_ENABLED +// #define MBEDTLS_ECP_DP_SECP521R1_ENABLED +// #define MBEDTLS_ECP_DP_SECP192K1_ENABLED +// #define MBEDTLS_ECP_DP_SECP224K1_ENABLED +// #define MBEDTLS_ECP_DP_SECP256K1_ENABLED +// #define MBEDTLS_ECP_DP_BP256R1_ENABLED +// #define MBEDTLS_ECP_DP_BP384R1_ENABLED +// #define MBEDTLS_ECP_DP_BP512R1_ENABLED +// #define MBEDTLS_ECP_DP_CURVE25519_ENABLED + +/** + * \def MBEDTLS_ECP_NIST_OPTIM + * + * Enable specific 'modulo p' routines for each NIST prime. + * Depending on the prime and architecture, makes operations 4 to 8 times + * faster on the corresponding curve. + * + * Comment this macro to disable NIST curves optimisation. + */ +// #define MBEDTLS_ECP_NIST_OPTIM + +/** + * \def MBEDTLS_ECDSA_DETERMINISTIC + * + * Enable deterministic ECDSA (RFC 6979). + * Standard ECDSA is "fragile" in the sense that lack of entropy when signing + * may result in a compromise of the long-term signing key. This is avoided by + * the deterministic variant. + * + * Requires: MBEDTLS_HMAC_DRBG_C + * + * Comment this macro to disable deterministic ECDSA. + */ +// #define MBEDTLS_ECDSA_DETERMINISTIC + +/** + * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED + * + * Enable the PSK based ciphersuite modes in SSL / TLS. + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA + */ +// #define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED + * + * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_DHM_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA + */ +// #define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED + * + * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA + */ +// #define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED + * + * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA + */ +// #define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED + * + * Enable the RSA-only based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 + */ +// #define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED + * + * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + */ +// #define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED + * + * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA + */ +// #define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + * + * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C, + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + */ +// #define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + * + * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +// #define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED + * + * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +// #define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED + * + * Enable the ECJPAKE based ciphersuite modes in SSL / TLS. + * + * \warning This is currently experimental. EC J-PAKE support is based on the + * Thread v1.0.0 specification; incompatible changes to the specification + * might still happen. For this reason, this is disabled by default. + * + * Requires: MBEDTLS_ECJPAKE_C + * MBEDTLS_SHA256_C + * MBEDTLS_ECP_DP_SECP256R1_ENABLED + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 + */ +//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED + +/** + * \def MBEDTLS_PK_PARSE_EC_EXTENDED + * + * Enhance support for reading EC keys using variants of SEC1 not allowed by + * RFC 5915 and RFC 5480. + * + * Currently this means parsing the SpecifiedECDomain choice of EC + * parameters (only known groups are supported, not arbitrary domains, to + * avoid validation issues). + * + * Disable if you only need to support RFC 5915 + 5480 key formats. + */ +// #define MBEDTLS_PK_PARSE_EC_EXTENDED + +/** + * \def MBEDTLS_ERROR_STRERROR_DUMMY + * + * Enable a dummy error function to make use of mbedtls_strerror() in + * third party libraries easier when MBEDTLS_ERROR_C is disabled + * (no effect when MBEDTLS_ERROR_C is enabled). + * + * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're + * not using mbedtls_strerror() or error_strerror() in your application. + * + * Disable if you run into name conflicts and want to really remove the + * mbedtls_strerror() + */ +// #define MBEDTLS_ERROR_STRERROR_DUMMY + +/** + * \def MBEDTLS_GENPRIME + * + * Enable the prime-number generation code. + * + * Requires: MBEDTLS_BIGNUM_C + */ +// #define MBEDTLS_GENPRIME + +/** + * \def MBEDTLS_FS_IO + * + * Enable functions that use the filesystem. + */ +//#define MBEDTLS_FS_IO + +/** + * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + * Do not add default entropy sources. These are the platform specific, + * mbedtls_timing_hardclock and HAVEGE based poll functions. + * + * This is useful to have more control over the added entropy sources in an + * application. + * + * Uncomment this macro to prevent loading of default entropy functions. + */ +//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + +/** + * \def MBEDTLS_NO_PLATFORM_ENTROPY + * + * Do not use built-in platform entropy functions. + * This is useful if your platform does not support + * standards like the /dev/urandom or Windows CryptoAPI. + * + * Uncomment this macro to disable the built-in platform entropy functions. + */ +// #define MBEDTLS_NO_PLATFORM_ENTROPY + +/** + * \def MBEDTLS_ENTROPY_FORCE_SHA256 + * + * Force the entropy accumulator to use a SHA-256 accumulator instead of the + * default SHA-512 based one (if both are available). + * + * Requires: MBEDTLS_SHA256_C + * + * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option + * if you have performance concerns. + * + * This option is only useful if both MBEDTLS_SHA256_C and + * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. + */ +//#define MBEDTLS_ENTROPY_FORCE_SHA256 + +/** + * \def MBEDTLS_ENTROPY_NV_SEED + * + * Enable the non-volatile (NV) seed file-based entropy source. + * (Also enables the NV seed read/write functions in the platform layer) + * + * This is crucial (if not required) on systems that do not have a + * cryptographic entropy source (in hardware or kernel) available. + * + * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C + * + * \note The read/write functions that are used by the entropy source are + * determined in the platform layer, and can be modified at runtime and/or + * compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used. + * + * \note If you use the default implementation functions that read a seedfile + * with regular fopen(), please make sure you make a seedfile with the + * proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at + * least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from + * and written to or you will get an entropy source error! The default + * implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE + * bytes from the file. + * + * \note The entropy collector will write to the seed file before entropy is + * given to an external source, to update it. + */ +//#define MBEDTLS_ENTROPY_NV_SEED + +/** + * \def MBEDTLS_MEMORY_DEBUG + * + * Enable debugging of buffer allocator memory issues. Automatically prints + * (to stderr) all (fatal) messages on memory allocation issues. Enables + * function for 'debug output' of allocated memory. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Uncomment this macro to let the buffer allocator print out error messages. + */ +//#define MBEDTLS_MEMORY_DEBUG + +/** + * \def MBEDTLS_MEMORY_BACKTRACE + * + * Include backtrace information with each allocated block. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * GLIBC-compatible backtrace() an backtrace_symbols() support + * + * Uncomment this macro to include backtrace information + */ +//#define MBEDTLS_MEMORY_BACKTRACE + +/** + * \def MBEDTLS_PK_RSA_ALT_SUPPORT + * + * Support external private RSA keys (eg from a HSM) in the PK layer. + * + * Comment this macro to disable support for external private RSA keys. + */ +// #define MBEDTLS_PK_RSA_ALT_SUPPORT + +/** + * \def MBEDTLS_PKCS1_V15 + * + * Enable support for PKCS#1 v1.5 encoding. + * + * Requires: MBEDTLS_RSA_C + * + * This enables support for PKCS#1 v1.5 operations. + */ +// #define MBEDTLS_PKCS1_V15 + +/** + * \def MBEDTLS_PKCS1_V21 + * + * Enable support for PKCS#1 v2.1 encoding. + * + * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C + * + * This enables support for RSAES-OAEP and RSASSA-PSS operations. + */ +// #define MBEDTLS_PKCS1_V21 + +/** + * \def MBEDTLS_RSA_NO_CRT + * + * Do not use the Chinese Remainder Theorem for the RSA private operation. + * + * Uncomment this macro to disable the use of CRT in RSA. + * + */ +//#define MBEDTLS_RSA_NO_CRT + +/** + * \def MBEDTLS_SELF_TEST + * + * Enable the checkup functions (*_self_test). + */ +// #define MBEDTLS_SELF_TEST + +/** + * \def MBEDTLS_SHA256_SMALLER + * + * Enable an implementation of SHA-256 that has lower ROM footprint but also + * lower performance. + * + * The default implementation is meant to be a reasonnable compromise between + * performance and size. This version optimizes more aggressively for size at + * the expense of performance. Eg on Cortex-M4 it reduces the size of + * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about + * 30%. + * + * Uncomment to enable the smaller implementation of SHA256. + */ +//#define MBEDTLS_SHA256_SMALLER + +/** + * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES + * + * Enable sending of alert messages in case of encountered errors as per RFC. + * If you choose not to send the alert messages, mbed TLS can still communicate + * with other servers, only debugging of failures is harder. + * + * The advantage of not sending alert messages, is that no information is given + * about reasons for failures thus preventing adversaries of gaining intel. + * + * Enable sending of all alert messages + */ +// #define MBEDTLS_SSL_ALL_ALERT_MESSAGES + +/** + * \def MBEDTLS_SSL_DEBUG_ALL + * + * Enable the debug messages in SSL module for all issues. + * Debug messages have been disabled in some places to prevent timing + * attacks due to (unbalanced) debugging function calls. + * + * If you need all error reporting you should enable this during debugging, + * but remove this for production servers that should log as well. + * + * Uncomment this macro to report all debug messages on errors introducing + * a timing side-channel. + * + */ +//#define MBEDTLS_SSL_DEBUG_ALL + +/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC + * + * Enable support for Encrypt-then-MAC, RFC 7366. + * + * This allows peers that both support it to use a more robust protection for + * ciphersuites using CBC, providing deep resistance against timing attacks + * on the padding or underlying cipher. + * + * This only affects CBC ciphersuites, and is useless if none is defined. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1 or + * MBEDTLS_SSL_PROTO_TLS1_1 or + * MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for Encrypt-then-MAC + */ +// #define MBEDTLS_SSL_ENCRYPT_THEN_MAC + +/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET + * + * Enable support for Extended Master Secret, aka Session Hash + * (draft-ietf-tls-session-hash-02). + * + * This was introduced as "the proper fix" to the Triple Handshake familiy of + * attacks, but it is recommended to always use it (even if you disable + * renegotiation), since it actually fixes a more fundamental issue in the + * original SSL/TLS design, and has implications beyond Triple Handshake. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1 or + * MBEDTLS_SSL_PROTO_TLS1_1 or + * MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for Extended Master Secret. + */ +// #define MBEDTLS_SSL_EXTENDED_MASTER_SECRET + +/** + * \def MBEDTLS_SSL_FALLBACK_SCSV + * + * Enable support for FALLBACK_SCSV (draft-ietf-tls-downgrade-scsv-00). + * + * For servers, it is recommended to always enable this, unless you support + * only one version of TLS, or know for sure that none of your clients + * implements a fallback strategy. + * + * For clients, you only need this if you're using a fallback strategy, which + * is not recommended in the first place, unless you absolutely need it to + * interoperate with buggy (version-intolerant) servers. + * + * Comment this macro to disable support for FALLBACK_SCSV + */ +// #define MBEDTLS_SSL_FALLBACK_SCSV + +/** + * \def MBEDTLS_SSL_HW_RECORD_ACCEL + * + * Enable hooking functions in SSL module for hardware acceleration of + * individual records. + * + * Uncomment this macro to enable hooking functions. + */ +//#define MBEDTLS_SSL_HW_RECORD_ACCEL + +/** + * \def MBEDTLS_SSL_CBC_RECORD_SPLITTING + * + * Enable 1/n-1 record splitting for CBC mode in SSLv3 and TLS 1.0. + * + * This is a countermeasure to the BEAST attack, which also minimizes the risk + * of interoperability issues compared to sending 0-length records. + * + * Comment this macro to disable 1/n-1 record splitting. + */ +// #define MBEDTLS_SSL_CBC_RECORD_SPLITTING + +/** + * \def MBEDTLS_SSL_RENEGOTIATION + * + * Disable support for TLS renegotiation. + * + * The two main uses of renegotiation are (1) refresh keys on long-lived + * connections and (2) client authentication after the initial handshake. + * If you don't need renegotiation, it's probably better to disable it, since + * it has been associated with security issues in the past and is easy to + * misuse/misunderstand. + * + * Comment this to disable support for renegotiation. + */ +// #define MBEDTLS_SSL_RENEGOTIATION + +/** + * \def MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + * + * Enable support for receiving and parsing SSLv2 Client Hello messages for the + * SSL Server module (MBEDTLS_SSL_SRV_C). + * + * Uncomment this macro to enable support for SSLv2 Client Hello messages. + */ +//#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + +/** + * \def MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE + * + * Pick the ciphersuite according to the client's preferences rather than ours + * in the SSL Server module (MBEDTLS_SSL_SRV_C). + * + * Uncomment this macro to respect client's ciphersuite order + */ +//#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE + +/** + * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + * + * Enable support for RFC 6066 max_fragment_length extension in SSL. + * + * Comment this macro to disable support for the max_fragment_length extension + */ +// #define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + +/** + * \def MBEDTLS_SSL_PROTO_SSL3 + * + * Enable support for SSL 3.0. + * + * Requires: MBEDTLS_MD5_C + * MBEDTLS_SHA1_C + * + * Comment this macro to disable support for SSL 3.0 + */ +//#define MBEDTLS_SSL_PROTO_SSL3 + +/** + * \def MBEDTLS_SSL_PROTO_TLS1 + * + * Enable support for TLS 1.0. + * + * Requires: MBEDTLS_MD5_C + * MBEDTLS_SHA1_C + * + * Comment this macro to disable support for TLS 1.0 + */ +// #define MBEDTLS_SSL_PROTO_TLS1 + +/** + * \def MBEDTLS_SSL_PROTO_TLS1_1 + * + * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled). + * + * Requires: MBEDTLS_MD5_C + * MBEDTLS_SHA1_C + * + * Comment this macro to disable support for TLS 1.1 / DTLS 1.0 + */ +// #define MBEDTLS_SSL_PROTO_TLS1_1 + +/** + * \def MBEDTLS_SSL_PROTO_TLS1_2 + * + * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled). + * + * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C + * (Depends on ciphersuites) + * + * Comment this macro to disable support for TLS 1.2 / DTLS 1.2 + */ +// #define MBEDTLS_SSL_PROTO_TLS1_2 + +/** + * \def MBEDTLS_SSL_PROTO_DTLS + * + * Enable support for DTLS (all available versions). + * + * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0, + * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1_1 + * or MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for DTLS + */ +// #define MBEDTLS_SSL_PROTO_DTLS + +/** + * \def MBEDTLS_SSL_ALPN + * + * Enable support for RFC 7301 Application Layer Protocol Negotiation. + * + * Comment this macro to disable support for ALPN. + */ +// #define MBEDTLS_SSL_ALPN + +/** + * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY + * + * Enable support for the anti-replay mechanism in DTLS. + * + * Requires: MBEDTLS_SSL_TLS_C + * MBEDTLS_SSL_PROTO_DTLS + * + * \warning Disabling this is often a security risk! + * See mbedtls_ssl_conf_dtls_anti_replay() for details. + * + * Comment this to disable anti-replay in DTLS. + */ +// #define MBEDTLS_SSL_DTLS_ANTI_REPLAY + +/** + * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY + * + * Enable support for HelloVerifyRequest on DTLS servers. + * + * This feature is highly recommended to prevent DTLS servers being used as + * amplifiers in DoS attacks against other hosts. It should always be enabled + * unless you know for sure amplification cannot be a problem in the + * environment in which your server operates. + * + * \warning Disabling this can ba a security risk! (see above) + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + * + * Comment this to disable support for HelloVerifyRequest. + */ +// #define MBEDTLS_SSL_DTLS_HELLO_VERIFY + +/** + * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE + * + * Enable server-side support for clients that reconnect from the same port. + * + * Some clients unexpectedly close the connection and try to reconnect using the + * same source port. This needs special support from the server to handle the + * new connection securely, as described in section 4.2.8 of RFC 6347. This + * flag enables that support. + * + * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY + * + * Comment this to disable support for clients reusing the source port. + */ +// #define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE + +/** + * \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT + * + * Enable support for a limit of records with bad MAC. + * + * See mbedtls_ssl_conf_dtls_badmac_limit(). + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + */ +// #define MBEDTLS_SSL_DTLS_BADMAC_LIMIT + +/** + * \def MBEDTLS_SSL_SESSION_TICKETS + * + * Enable support for RFC 5077 session tickets in SSL. + * Client-side, provides full support for session tickets (maintainance of a + * session store remains the responsibility of the application, though). + * Server-side, you also need to provide callbacks for writing and parsing + * tickets, including authenticated encryption and key management. Example + * callbacks are provided by MBEDTLS_SSL_TICKET_C. + * + * Comment this macro to disable support for SSL session tickets + */ +// #define MBEDTLS_SSL_SESSION_TICKETS + +/** + * \def MBEDTLS_SSL_EXPORT_KEYS + * + * Enable support for exporting key block and master secret. + * This is required for certain users of TLS, e.g. EAP-TLS. + * + * Comment this macro to disable support for key export + */ +// #define MBEDTLS_SSL_EXPORT_KEYS + +/** + * \def MBEDTLS_SSL_SERVER_NAME_INDICATION + * + * Enable support for RFC 6066 server name indication (SNI) in SSL. + * + * Requires: MBEDTLS_X509_CRT_PARSE_C + * + * Comment this macro to disable support for server name indication in SSL + */ +// #define MBEDTLS_SSL_SERVER_NAME_INDICATION + +/** + * \def MBEDTLS_SSL_TRUNCATED_HMAC + * + * Enable support for RFC 6066 truncated HMAC in SSL. + * + * Comment this macro to disable support for truncated HMAC in SSL + */ +// #define MBEDTLS_SSL_TRUNCATED_HMAC + +/** + * \def MBEDTLS_THREADING_ALT + * + * Provide your own alternate threading implementation. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to allow your own alternate threading implementation. + */ +//#define MBEDTLS_THREADING_ALT + +/** + * \def MBEDTLS_THREADING_PTHREAD + * + * Enable the pthread wrapper layer for the threading layer. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to enable pthread mutexes. + */ +//#define MBEDTLS_THREADING_PTHREAD + +/** + * \def MBEDTLS_VERSION_FEATURES + * + * Allow run-time checking of compile-time enabled features. Thus allowing users + * to check at run-time if the library is for instance compiled with threading + * support via mbedtls_version_check_feature(). + * + * Requires: MBEDTLS_VERSION_C + * + * Comment this to disable run-time checking and save ROM space + */ +// #define MBEDTLS_VERSION_FEATURES + +/** + * \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an extension in a v1 or v2 certificate. + * + * Uncomment to prevent an error. + */ +//#define MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 + +/** + * \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an unknown critical extension. + * + * \warning Depending on your PKI use, enabling this can be a security risk! + * + * Uncomment to prevent an error. + */ +//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + +/** + * \def MBEDTLS_X509_CHECK_KEY_USAGE + * + * Enable verification of the keyUsage extension (CA and leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused + * (intermediate) CA and leaf certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip keyUsage checking for both CA and leaf certificates. + */ +// #define MBEDTLS_X509_CHECK_KEY_USAGE + +/** + * \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE + * + * Enable verification of the extendedKeyUsage extension (leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip extendedKeyUsage checking for certificates. + */ +// #define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE + +/** + * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT + * + * Enable parsing and verification of X.509 certificates, CRLs and CSRS + * signed with RSASSA-PSS (aka PKCS#1 v2.1). + * + * Comment this macro to disallow using RSASSA-PSS in certificates. + */ +// #define MBEDTLS_X509_RSASSA_PSS_SUPPORT + +/** + * \def MBEDTLS_ZLIB_SUPPORT + * + * If set, the SSL/TLS module uses ZLIB to support compression and + * decompression of packet data. + * + * \warning TLS-level compression MAY REDUCE SECURITY! See for example the + * CRIME attack. Before enabling this option, you should examine with care if + * CRIME or similar exploits may be a applicable to your use case. + * + * \note Currently compression can't be used with DTLS. + * + * Used in: library/ssl_tls.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * This feature requires zlib library and headers to be present. + * + * Uncomment to enable use of ZLIB + */ +//#define MBEDTLS_ZLIB_SUPPORT +/* \} name SECTION: mbed TLS feature support */ + +/** + * \name SECTION: mbed TLS modules + * + * This section enables or disables entire modules in mbed TLS + * \{ + */ + +/** + * \def MBEDTLS_AESNI_C + * + * Enable AES-NI support on x86-64. + * + * Module: library/aesni.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the AES-NI instructions on x86-64 + */ +// #define MBEDTLS_AESNI_C + +/** + * \def MBEDTLS_AES_C + * + * Enable the AES block cipher. + * + * Module: library/aes.c + * Caller: library/ssl_tls.c + * library/pem.c + * library/ctr_drbg.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA + * + * PEM_PARSE uses AES for decrypting encrypted keys. + */ +#define MBEDTLS_AES_C + +/** + * \def MBEDTLS_ARC4_C + * + * Enable the ARCFOUR stream cipher. + * + * Module: library/arc4.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA + * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA + * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 + * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA + * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA + */ +// #define MBEDTLS_ARC4_C + +/** + * \def MBEDTLS_ASN1_PARSE_C + * + * Enable the generic ASN1 parser. + * + * Module: library/asn1.c + * Caller: library/x509.c + * library/dhm.c + * library/pkcs12.c + * library/pkcs5.c + * library/pkparse.c + */ +// #define MBEDTLS_ASN1_PARSE_C + +/** + * \def MBEDTLS_ASN1_WRITE_C + * + * Enable the generic ASN1 writer. + * + * Module: library/asn1write.c + * Caller: library/ecdsa.c + * library/pkwrite.c + * library/x509_create.c + * library/x509write_crt.c + * library/x509write_csr.c + */ +// #define MBEDTLS_ASN1_WRITE_C + +/** + * \def MBEDTLS_BASE64_C + * + * Enable the Base64 module. + * + * Module: library/base64.c + * Caller: library/pem.c + * + * This module is required for PEM support (required by X.509). + */ +// #define MBEDTLS_BASE64_C + +/** + * \def MBEDTLS_BIGNUM_C + * + * Enable the multi-precision integer library. + * + * Module: library/bignum.c + * Caller: library/dhm.c + * library/ecp.c + * library/ecdsa.c + * library/rsa.c + * library/ssl_tls.c + * + * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. + */ +// #define MBEDTLS_BIGNUM_C + +/** + * \def MBEDTLS_BLOWFISH_C + * + * Enable the Blowfish block cipher. + * + * Module: library/blowfish.c + */ +// #define MBEDTLS_BLOWFISH_C + +/** + * \def MBEDTLS_CAMELLIA_C + * + * Enable the Camellia block cipher. + * + * Module: library/camellia.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + */ +// #define MBEDTLS_CAMELLIA_C + +/** + * \def MBEDTLS_CCM_C + * + * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. + * + * Module: library/ccm.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C + * + * This module enables the AES-CCM ciphersuites, if other requisites are + * enabled as well. + */ +#define MBEDTLS_CCM_C + +/** + * \def MBEDTLS_CERTS_C + * + * Enable the test certificates. + * + * Module: library/certs.c + * Caller: + * + * This module is used for testing (ssl_client/server). + */ +// #define MBEDTLS_CERTS_C + +/** + * \def MBEDTLS_CIPHER_C + * + * Enable the generic cipher layer. + * + * Module: library/cipher.c + * Caller: library/ssl_tls.c + * + * Uncomment to enable generic cipher wrappers. + */ +#define MBEDTLS_CIPHER_C + +/** + * \def MBEDTLS_CMAC_C + * + * Enable the CMAC (Cipher-based Message Authentication Code) mode for block + * ciphers. + * + * Module: library/cmac.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C + * + */ +//#define MBEDTLS_CMAC_C + +/** + * \def MBEDTLS_CTR_DRBG_C + * + * Enable the CTR_DRBG AES-256-based random generator. + * + * Module: library/ctr_drbg.c + * Caller: + * + * Requires: MBEDTLS_AES_C + * + * This module provides the CTR_DRBG AES-256 random number generator. + */ +// #define MBEDTLS_CTR_DRBG_C + +/** + * \def MBEDTLS_DEBUG_C + * + * Enable the debug functions. + * + * Module: library/debug.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module provides debugging functions. + */ +// #define MBEDTLS_DEBUG_C + +/** + * \def MBEDTLS_DES_C + * + * Enable the DES block cipher. + * + * Module: library/des.c + * Caller: library/pem.c + * library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA + * + * PEM_PARSE uses DES/3DES for decrypting encrypted keys. + */ +// #define MBEDTLS_DES_C + +/** + * \def MBEDTLS_DHM_C + * + * Enable the Diffie-Hellman-Merkle module. + * + * Module: library/dhm.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module is used by the following key exchanges: + * DHE-RSA, DHE-PSK + */ +// #define MBEDTLS_DHM_C + +/** + * \def MBEDTLS_ECDH_C + * + * Enable the elliptic curve Diffie-Hellman library. + * + * Module: library/ecdh.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK + * + * Requires: MBEDTLS_ECP_C + */ +// #define MBEDTLS_ECDH_C + +/** + * \def MBEDTLS_ECDSA_C + * + * Enable the elliptic curve DSA library. + * + * Module: library/ecdsa.c + * Caller: + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA + * + * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C + */ +// #define MBEDTLS_ECDSA_C + +/** + * \def MBEDTLS_ECJPAKE_C + * + * Enable the elliptic curve J-PAKE library. + * + * \warning This is currently experimental. EC J-PAKE support is based on the + * Thread v1.0.0 specification; incompatible changes to the specification + * might still happen. For this reason, this is disabled by default. + * + * Module: library/ecjpake.c + * Caller: + * + * This module is used by the following key exchanges: + * ECJPAKE + * + * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C + */ +//#define MBEDTLS_ECJPAKE_C + +/** + * \def MBEDTLS_ECP_C + * + * Enable the elliptic curve over GF(p) library. + * + * Module: library/ecp.c + * Caller: library/ecdh.c + * library/ecdsa.c + * library/ecjpake.c + * + * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED + */ +// #define MBEDTLS_ECP_C + +/** + * \def MBEDTLS_ENTROPY_C + * + * Enable the platform-specific entropy code. + * + * Module: library/entropy.c + * Caller: + * + * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C + * + * This module provides a generic entropy pool + */ +// #define MBEDTLS_ENTROPY_C + +/** + * \def MBEDTLS_ERROR_C + * + * Enable error code to error string conversion. + * + * Module: library/error.c + * Caller: + * + * This module enables mbedtls_strerror(). + */ +// #define MBEDTLS_ERROR_C + +/** + * \def MBEDTLS_GCM_C + * + * Enable the Galois/Counter Mode (GCM) for AES. + * + * Module: library/gcm.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C + * + * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other + * requisites are enabled as well. + */ +// #define MBEDTLS_GCM_C + +/** + * \def MBEDTLS_HAVEGE_C + * + * Enable the HAVEGE random generator. + * + * Warning: the HAVEGE random generator is not suitable for virtualized + * environments + * + * Warning: the HAVEGE random generator is dependent on timing and specific + * processor traits. It is therefore not advised to use HAVEGE as + * your applications primary random generator or primary entropy pool + * input. As a secondary input to your entropy pool, it IS able add + * the (limited) extra entropy it provides. + * + * Module: library/havege.c + * Caller: + * + * Requires: MBEDTLS_TIMING_C + * + * Uncomment to enable the HAVEGE random generator. + */ +//#define MBEDTLS_HAVEGE_C + +/** + * \def MBEDTLS_HMAC_DRBG_C + * + * Enable the HMAC_DRBG random generator. + * + * Module: library/hmac_drbg.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * Uncomment to enable the HMAC_DRBG random number geerator. + */ +// #define MBEDTLS_HMAC_DRBG_C + +/** + * \def MBEDTLS_MD_C + * + * Enable the generic message digest layer. + * + * Module: library/md.c + * Caller: + * + * Uncomment to enable generic message digest wrappers. + */ +// #define MBEDTLS_MD_C + +/** + * \def MBEDTLS_MD2_C + * + * Enable the MD2 hash algorithm. + * + * Module: library/md2.c + * Caller: + * + * Uncomment to enable support for (rare) MD2-signed X.509 certs. + */ +//#define MBEDTLS_MD2_C + +/** + * \def MBEDTLS_MD4_C + * + * Enable the MD4 hash algorithm. + * + * Module: library/md4.c + * Caller: + * + * Uncomment to enable support for (rare) MD4-signed X.509 certs. + */ +//#define MBEDTLS_MD4_C + +/** + * \def MBEDTLS_MD5_C + * + * Enable the MD5 hash algorithm. + * + * Module: library/md5.c + * Caller: library/md.c + * library/pem.c + * library/ssl_tls.c + * + * This module is required for SSL/TLS and X.509. + * PEM_PARSE uses MD5 for decrypting encrypted keys. + */ +// #define MBEDTLS_MD5_C + +/** + * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Enable the buffer allocator implementation that makes use of a (stack) + * based buffer to 'allocate' dynamic memory. (replaces calloc() and free() + * calls) + * + * Module: library/memory_buffer_alloc.c + * + * Requires: MBEDTLS_PLATFORM_C + * MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS) + * + * Enable this module to enable the buffer memory allocator. + */ +//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C + +/** + * \def MBEDTLS_NET_C + * + * Enable the TCP and UDP over IPv6/IPv4 networking routines. + * + * \note This module only works on POSIX/Unix (including Linux, BSD and OS X) + * and Windows. For other platforms, you'll want to disable it, and write your + * own networking callbacks to be passed to \c mbedtls_ssl_set_bio(). + * + * \note See also our Knowledge Base article about porting to a new + * environment: + * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS + * + * Module: library/net_sockets.c + * + * This module provides networking routines. + */ +//#define MBEDTLS_NET_C + +/** + * \def MBEDTLS_OID_C + * + * Enable the OID database. + * + * Module: library/oid.c + * Caller: library/asn1write.c + * library/pkcs5.c + * library/pkparse.c + * library/pkwrite.c + * library/rsa.c + * library/x509.c + * library/x509_create.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * This modules translates between OIDs and internal values. + */ +#define MBEDTLS_OID_C + +/** + * \def MBEDTLS_PADLOCK_C + * + * Enable VIA Padlock support on x86. + * + * Module: library/padlock.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the VIA PadLock on x86. + */ +// #define MBEDTLS_PADLOCK_C + +/** + * \def MBEDTLS_PEM_PARSE_C + * + * Enable PEM decoding / parsing. + * + * Module: library/pem.c + * Caller: library/dhm.c + * library/pkparse.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for decoding / parsing PEM files. + */ +// #define MBEDTLS_PEM_PARSE_C + +/** + * \def MBEDTLS_PEM_WRITE_C + * + * Enable PEM encoding / writing. + * + * Module: library/pem.c + * Caller: library/pkwrite.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for encoding / writing PEM files. + */ +// // #define MBEDTLS_PEM_WRITE_C + +/** + * \def MBEDTLS_PK_C + * + * Enable the generic public (asymetric) key layer. + * + * Module: library/pk.c + * Caller: library/ssl_tls.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C + * + * Uncomment to enable generic public key wrappers. + */ +// #define MBEDTLS_PK_C + +/** + * \def MBEDTLS_PK_PARSE_C + * + * Enable the generic public (asymetric) key parser. + * + * Module: library/pkparse.c + * Caller: library/x509_crt.c + * library/x509_csr.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key parse functions. + */ +// #define MBEDTLS_PK_PARSE_C + +/** + * \def MBEDTLS_PK_WRITE_C + * + * Enable the generic public (asymetric) key writer. + * + * Module: library/pkwrite.c + * Caller: library/x509write.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key write functions. + */ +// #define MBEDTLS_PK_WRITE_C + +/** + * \def MBEDTLS_PKCS5_C + * + * Enable PKCS#5 functions. + * + * Module: library/pkcs5.c + * + * Requires: MBEDTLS_MD_C + * + * This module adds support for the PKCS#5 functions. + */ +// #define MBEDTLS_PKCS5_C + +/** + * \def MBEDTLS_PKCS11_C + * + * Enable wrapper for PKCS#11 smartcard support. + * + * Module: library/pkcs11.c + * Caller: library/pk.c + * + * Requires: MBEDTLS_PK_C + * + * This module enables SSL/TLS PKCS #11 smartcard support. + * Requires the presence of the PKCS#11 helper library (libpkcs11-helper) + */ +//#define MBEDTLS_PKCS11_C + +/** + * \def MBEDTLS_PKCS12_C + * + * Enable PKCS#12 PBE functions. + * Adds algorithms for parsing PKCS#8 encrypted private keys + * + * Module: library/pkcs12.c + * Caller: library/pkparse.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C + * Can use: MBEDTLS_ARC4_C + * + * This module enables PKCS#12 functions. + */ +// #define MBEDTLS_PKCS12_C + +/** + * \def MBEDTLS_PLATFORM_C + * + * Enable the platform abstraction layer that allows you to re-assign + * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). + * + * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT + * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned + * above to be specified at runtime or compile time respectively. + * + * \note This abstraction layer must be enabled on Windows (including MSYS2) + * as other module rely on it for a fixed snprintf implementation. + * + * Module: library/platform.c + * Caller: Most other .c files + * + * This module enables abstraction of common (libc) functions. + */ +// #define MBEDTLS_PLATFORM_C + +/** + * \def MBEDTLS_RIPEMD160_C + * + * Enable the RIPEMD-160 hash algorithm. + * + * Module: library/ripemd160.c + * Caller: library/md.c + * + */ +// #define MBEDTLS_RIPEMD160_C + +/** + * \def MBEDTLS_RSA_C + * + * Enable the RSA public-key cryptosystem. + * + * Module: library/rsa.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509.c + * + * This module is used by the following key exchanges: + * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK + * + * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C + */ +// #define MBEDTLS_RSA_C + +/** + * \def MBEDTLS_SHA1_C + * + * Enable the SHA1 cryptographic hash algorithm. + * + * Module: library/sha1.c + * Caller: library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509write_crt.c + * + * This module is required for SSL/TLS and SHA1-signed certificates. + */ +// #define MBEDTLS_SHA1_C + +/** + * \def MBEDTLS_SHA256_C + * + * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. + * + * Module: library/sha256.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module adds support for SHA-224 and SHA-256. + * This module is required for the SSL/TLS 1.2 PRF function. + */ +// #define MBEDTLS_SHA256_C + +/** + * \def MBEDTLS_SHA512_C + * + * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. + * + * Module: library/sha512.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * This module adds support for SHA-384 and SHA-512. + */ +// #define MBEDTLS_SHA512_C + +/** + * \def MBEDTLS_SSL_CACHE_C + * + * Enable simple SSL cache implementation. + * + * Module: library/ssl_cache.c + * Caller: + * + * Requires: MBEDTLS_SSL_CACHE_C + */ +// #define MBEDTLS_SSL_CACHE_C + +/** + * \def MBEDTLS_SSL_COOKIE_C + * + * Enable basic implementation of DTLS cookies for hello verification. + * + * Module: library/ssl_cookie.c + * Caller: + */ +// #define MBEDTLS_SSL_COOKIE_C + +/** + * \def MBEDTLS_SSL_TICKET_C + * + * Enable an implementation of TLS server-side callbacks for session tickets. + * + * Module: library/ssl_ticket.c + * Caller: + * + * Requires: MBEDTLS_CIPHER_C + */ +// #define MBEDTLS_SSL_TICKET_C + +/** + * \def MBEDTLS_SSL_CLI_C + * + * Enable the SSL/TLS client code. + * + * Module: library/ssl_cli.c + * Caller: + * + * Requires: MBEDTLS_SSL_TLS_C + * + * This module is required for SSL/TLS client support. + */ +// #define MBEDTLS_SSL_CLI_C + +/** + * \def MBEDTLS_SSL_SRV_C + * + * Enable the SSL/TLS server code. + * + * Module: library/ssl_srv.c + * Caller: + * + * Requires: MBEDTLS_SSL_TLS_C + * + * This module is required for SSL/TLS server support. + */ +// #define MBEDTLS_SSL_SRV_C + +/** + * \def MBEDTLS_SSL_TLS_C + * + * Enable the generic SSL/TLS code. + * + * Module: library/ssl_tls.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C + * and at least one of the MBEDTLS_SSL_PROTO_XXX defines + * + * This module is required for SSL/TLS. + */ +// #define MBEDTLS_SSL_TLS_C + +/** + * \def MBEDTLS_THREADING_C + * + * Enable the threading abstraction layer. + * By default mbed TLS assumes it is used in a non-threaded environment or that + * contexts are not shared between threads. If you do intend to use contexts + * between threads, you will need to enable this layer to prevent race + * conditions. See also our Knowledge Base article about threading: + * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading + * + * Module: library/threading.c + * + * This allows different threading implementations (self-implemented or + * provided). + * + * You will have to enable either MBEDTLS_THREADING_ALT or + * MBEDTLS_THREADING_PTHREAD. + * + * Enable this layer to allow use of mutexes within mbed TLS + */ +//#define MBEDTLS_THREADING_C + +/** + * \def MBEDTLS_TIMING_C + * + * Enable the semi-portable timing interface. + * + * \note The provided implementation only works on POSIX/Unix (including Linux, + * BSD and OS X) and Windows. On other platforms, you can either disable that + * module and provide your own implementations of the callbacks needed by + * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide + * your own implementation of the whole module by setting + * \c MBEDTLS_TIMING_ALT in the current file. + * + * \note See also our Knowledge Base article about porting to a new + * environment: + * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS + * + * Module: library/timing.c + * Caller: library/havege.c + * + * This module is used by the HAVEGE random number generator. + */ +//#define MBEDTLS_TIMING_C + +/** + * \def MBEDTLS_VERSION_C + * + * Enable run-time version information. + * + * Module: library/version.c + * + * This module provides run-time version information. + */ +// #define MBEDTLS_VERSION_C + +/** + * \def MBEDTLS_X509_USE_C + * + * Enable X.509 core for using certificates. + * + * Module: library/x509.c + * Caller: library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, + * MBEDTLS_PK_PARSE_C + * + * This module is required for the X.509 parsing modules. + */ +// #define MBEDTLS_X509_USE_C + +/** + * \def MBEDTLS_X509_CRT_PARSE_C + * + * Enable X.509 certificate parsing. + * + * Module: library/x509_crt.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is required for X.509 certificate parsing. + */ +// #define MBEDTLS_X509_CRT_PARSE_C + +/** + * \def MBEDTLS_X509_CRL_PARSE_C + * + * Enable X.509 CRL parsing. + * + * Module: library/x509_crl.c + * Caller: library/x509_crt.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is required for X.509 CRL parsing. + */ +// #define MBEDTLS_X509_CRL_PARSE_C + +/** + * \def MBEDTLS_X509_CSR_PARSE_C + * + * Enable X.509 Certificate Signing Request (CSR) parsing. + * + * Module: library/x509_csr.c + * Caller: library/x509_crt_write.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is used for reading X.509 certificate request. + */ +// #define MBEDTLS_X509_CSR_PARSE_C + +/** + * \def MBEDTLS_X509_CREATE_C + * + * Enable X.509 core for creating certificates. + * + * Module: library/x509_create.c + * + * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_WRITE_C + * + * This module is the basis for creating X.509 certificates and CSRs. + */ +// #define MBEDTLS_X509_CREATE_C + +/** + * \def MBEDTLS_X509_CRT_WRITE_C + * + * Enable creating X.509 certificates. + * + * Module: library/x509_crt_write.c + * + * Requires: MBEDTLS_X509_CREATE_C + * + * This module is required for X.509 certificate creation. + */ +// #define MBEDTLS_X509_CRT_WRITE_C + +/** + * \def MBEDTLS_X509_CSR_WRITE_C + * + * Enable creating X.509 Certificate Signing Requests (CSR). + * + * Module: library/x509_csr_write.c + * + * Requires: MBEDTLS_X509_CREATE_C + * + * This module is required for X.509 certificate request writing. + */ +// #define MBEDTLS_X509_CSR_WRITE_C + +/** + * \def MBEDTLS_XTEA_C + * + * Enable the XTEA block cipher. + * + * Module: library/xtea.c + * Caller: + */ +// #define MBEDTLS_XTEA_C + +/* \} name SECTION: mbed TLS modules */ + +/** + * \name SECTION: Module configuration options + * + * This section allows for the setting of module specific sizes and + * configuration options. The default values are already present in the + * relevant header files and should suffice for the regular use cases. + * + * Our advice is to enable options and change their values here + * only if you have a good reason and know the consequences. + * + * Please check the respective header file for documentation on these + * parameters (to prevent duplicate documentation). + * \{ + */ + +/* MPI / BIGNUM options */ +//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ +//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ + +/* CTR_DRBG options */ +//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ +//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* HMAC_DRBG options */ +//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* ECP options */ +//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ +//#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ +//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ + +/* Entropy options */ +//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ +//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */ + +/* Memory buffer allocator options */ +//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ + +/* Platform options */ +//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ +//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +/* Note: your snprintf must correclty zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */ + +/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */ +/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ +//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ +/* Note: your snprintf must correclty zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ + +/* SSL Cache options */ +//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ +//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ + +/* SSL options */ +//#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */ +//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ +//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ +//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ + +/** + * Complete list of ciphersuites to use, in order of preference. + * + * \warning No dependency checking is done on that field! This option can only + * be used to restrict the set of available ciphersuites. It is your + * responsibility to make sure the needed modules are active. + * + * Use this to save a few hundred bytes of ROM (default ordering of all + * available ciphersuites) and a few to a few hundred bytes of RAM. + * + * The value below is only an example, not the default. + */ +//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + +/* X509 options */ +//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ +//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */ + +/* \} name SECTION: Customisation configuration options */ + +/* Target and application specific configurations */ +//#define YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE "mbedtls/target_config.h" + +#if defined(TARGET_LIKE_MBED) && defined(YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE) +#include YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE +#endif + +/* + * Allow user to override any previous default. + * + * Use two macro names for that, as: + * - with yotta the prefix YOTTA_CFG_ is forced + * - without yotta is looks weird to have a YOTTA prefix. + */ +#if defined(YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE) +#include YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE +#elif defined(MBEDTLS_USER_CONFIG_FILE) +#include MBEDTLS_USER_CONFIG_FILE +#endif + +#include "check_config.h" + +#endif /* MBEDTLS_CONFIG_H */ diff --git a/lib/mbedtls/include/mbedtls/platform.h b/lib/mbedtls/include/mbedtls/platform.h new file mode 100644 index 000000000..b1b019e55 --- /dev/null +++ b/lib/mbedtls/include/mbedtls/platform.h @@ -0,0 +1,295 @@ +/** + * \file platform.h + * + * \brief mbed TLS Platform abstraction layer + * + * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_PLATFORM_H +#define MBEDTLS_PLATFORM_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_HAVE_TIME) +#include "mbedtls/platform_time.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) +#include +#include +#include +#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) +#if defined(_WIN32) +#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< Default snprintf to use */ +#else +#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use */ +#endif +#endif +#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) +#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) +#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) +#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_FREE) +#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_EXIT) +#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_TIME) +#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) +#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS /**< Default exit value to use */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) +#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE /**< Default exit value to use */ +#endif +#if defined(MBEDTLS_FS_IO) +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) +#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read +#endif +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) +#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write +#endif +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE) +#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" +#endif +#endif /* MBEDTLS_FS_IO */ +#else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ +#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) +#include MBEDTLS_PLATFORM_STD_MEM_HDR +#endif +#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ + + +/* \} name SECTION: Module settings */ + +/* + * The function pointers for calloc and free + */ +#if defined(MBEDTLS_PLATFORM_MEMORY) +#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \ + defined(MBEDTLS_PLATFORM_CALLOC_MACRO) +#define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO +#define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO +#else +/* For size_t */ +#include +extern void * (*mbedtls_calloc)( size_t n, size_t size ); +extern void (*mbedtls_free)( void *ptr ); + +/** + * \brief Set your own memory implementation function pointers + * + * \param calloc_func the calloc function implementation + * \param free_func the free function implementation + * + * \return 0 if successful + */ +int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), + void (*free_func)( void * ) ); +#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */ +#else /* !MBEDTLS_PLATFORM_MEMORY */ +#define mbedtls_free free +#define mbedtls_calloc calloc +#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */ + +/* + * The function pointers for fprintf + */ +#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) +/* We need FILE * */ +#include +extern int (*mbedtls_fprintf)( FILE *stream, const char *format, ... ); + +/** + * \brief Set your own fprintf function pointer + * + * \param fprintf_func the fprintf function implementation + * + * \return 0 + */ +int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *, + ... ) ); +#else +#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) +#define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO +#else +#define mbedtls_fprintf fprintf +#endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */ +#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ + +/* + * The function pointers for printf + */ +#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) +extern int (*mbedtls_printf)( const char *format, ... ); + +/** + * \brief Set your own printf function pointer + * + * \param printf_func the printf function implementation + * + * \return 0 + */ +int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ); +#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */ +#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) +#define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO +#else +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */ +#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ + +/* + * The function pointers for snprintf + * + * The snprintf implementation should conform to C99: + * - it *must* always correctly zero-terminate the buffer + * (except when n == 0, then it must leave the buffer untouched) + * - however it is acceptable to return -1 instead of the required length when + * the destination buffer is too short. + */ +#if defined(_WIN32) +/* For Windows (inc. MSYS2), we provide our own fixed implementation */ +int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ); +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) +extern int (*mbedtls_snprintf)( char * s, size_t n, const char * format, ... ); + +/** + * \brief Set your own snprintf function pointer + * + * \param snprintf_func the snprintf function implementation + * + * \return 0 + */ +int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, + const char * format, ... ) ); +#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ +#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) +#define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO +#else +#define mbedtls_snprintf snprintf +#endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */ +#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ + +/* + * The function pointers for exit + */ +#if defined(MBEDTLS_PLATFORM_EXIT_ALT) +extern void (*mbedtls_exit)( int status ); + +/** + * \brief Set your own exit function pointer + * + * \param exit_func the exit function implementation + * + * \return 0 + */ +int mbedtls_platform_set_exit( void (*exit_func)( int status ) ); +#else +#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) +#define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO +#else +#define mbedtls_exit exit +#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */ +#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ + +/* + * The default exit values + */ +#if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) +#define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS +#else +#define MBEDTLS_EXIT_SUCCESS 0 +#endif +#if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) +#define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE +#else +#define MBEDTLS_EXIT_FAILURE 1 +#endif + +/* + * The function pointers for reading from and writing a seed file to + * Non-Volatile storage (NV) in a platform-independent way + * + * Only enabled when the NV seed entropy source is enabled + */ +#if defined(MBEDTLS_ENTROPY_NV_SEED) +#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) +/* Internal standard platform definitions */ +int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ); +int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ); +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +extern int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ); +extern int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ); + +/** + * \brief Set your own seed file writing/reading functions + * + * \param nv_seed_read_func the seed reading function implementation + * \param nv_seed_write_func the seed writing function implementation + * + * \return 0 + */ +int mbedtls_platform_set_nv_seed( + int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ), + int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) + ); +#else +#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \ + defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) +#define mbedtls_nv_seed_read MBEDTLS_PLATFORM_NV_SEED_READ_MACRO +#define mbedtls_nv_seed_write MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO +#else +#define mbedtls_nv_seed_read mbedtls_platform_std_nv_seed_read +#define mbedtls_nv_seed_write mbedtls_platform_std_nv_seed_write +#endif +#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ +#endif /* MBEDTLS_ENTROPY_NV_SEED */ + +#ifdef __cplusplus +} +#endif + +#endif /* platform.h */ diff --git a/lib/mbedtls/include/mbedtls/platform_time.h b/lib/mbedtls/include/mbedtls/platform_time.h new file mode 100644 index 000000000..abb343142 --- /dev/null +++ b/lib/mbedtls/include/mbedtls/platform_time.h @@ -0,0 +1,81 @@ +/** + * \file platform_time.h + * + * \brief mbed TLS Platform time abstraction + * + * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_PLATFORM_TIME_H +#define MBEDTLS_PLATFORM_TIME_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +/* + * The time_t datatype + */ +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) +typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t; +#else +/* For time_t */ +#include +typedef time_t mbedtls_time_t; +#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */ + +/* + * The function pointers for time + */ +#if defined(MBEDTLS_PLATFORM_TIME_ALT) +extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time ); + +/** + * \brief Set your own time function pointer + * + * \param time_func the time function implementation + * + * \return 0 + */ +int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) ); +#else +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) +#define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO +#else +#define mbedtls_time time +#endif /* MBEDTLS_PLATFORM_TIME_MACRO */ +#endif /* MBEDTLS_PLATFORM_TIME_ALT */ + +#ifdef __cplusplus +} +#endif + +#endif /* platform_time.h */ diff --git a/lib/mbedtls/src/aes.c b/lib/mbedtls/src/aes.c new file mode 100644 index 000000000..a186dee98 --- /dev/null +++ b/lib/mbedtls/src/aes.c @@ -0,0 +1,1492 @@ +/* + * FIPS-197 compliant AES implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. + * + * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf + * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_AES_C) + +#include + +#include "mbedtls/aes.h" +#if defined(MBEDTLS_PADLOCK_C) +#include "mbedtls/padlock.h" +#endif +#if defined(MBEDTLS_AESNI_C) +#include "mbedtls/aesni.h" +#endif + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_AES_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ + (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ + (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ + (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ +} +#endif + +#if defined(MBEDTLS_PADLOCK_C) && \ + ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) ) +static int aes_padlock_ace = -1; +#endif + +#if defined(MBEDTLS_AES_ROM_TABLES) +/* + * Forward S-box + */ +static const unsigned char FSb[256] = +{ + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, + 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, + 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, + 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, + 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, + 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, + 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, + 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, + 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, + 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, + 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, + 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, + 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, + 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, + 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, + 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, + 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 +}; + +/* + * Forward tables + */ +#define FT \ +\ + V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \ + V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \ + V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \ + V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \ + V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \ + V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \ + V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \ + V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \ + V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \ + V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \ + V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \ + V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \ + V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \ + V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \ + V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \ + V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \ + V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \ + V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \ + V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \ + V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \ + V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \ + V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \ + V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \ + V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \ + V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \ + V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \ + V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \ + V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \ + V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \ + V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \ + V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \ + V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \ + V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \ + V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \ + V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \ + V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \ + V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \ + V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \ + V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \ + V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \ + V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \ + V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \ + V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \ + V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \ + V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \ + V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \ + V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \ + V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \ + V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \ + V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \ + V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \ + V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \ + V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \ + V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \ + V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \ + V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \ + V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \ + V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \ + V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \ + V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \ + V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \ + V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \ + V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \ + V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C) + +#define V(a,b,c,d) 0x##a##b##c##d +static const uint32_t FT0[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##b##c##d##a +static const uint32_t FT1[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +static const uint32_t FT2[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##d##a##b##c +static const uint32_t FT3[256] = { FT }; +#undef V + +#undef FT + +/* + * Reverse S-box + */ +static const unsigned char RSb[256] = +{ + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, + 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, + 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, + 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, + 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, + 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, + 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, + 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, + 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, + 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, + 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, + 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, + 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, + 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, + 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, + 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D +}; + +/* + * Reverse tables + */ +#define RT \ +\ + V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \ + V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \ + V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \ + V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \ + V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \ + V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \ + V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \ + V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \ + V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \ + V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \ + V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \ + V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \ + V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \ + V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \ + V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \ + V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \ + V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \ + V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \ + V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \ + V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \ + V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \ + V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \ + V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \ + V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \ + V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \ + V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \ + V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \ + V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \ + V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \ + V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \ + V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \ + V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \ + V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \ + V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \ + V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \ + V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \ + V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \ + V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \ + V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \ + V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \ + V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \ + V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \ + V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \ + V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \ + V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \ + V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \ + V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \ + V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \ + V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \ + V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \ + V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \ + V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \ + V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \ + V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \ + V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \ + V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \ + V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \ + V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \ + V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \ + V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \ + V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \ + V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \ + V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \ + V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0) + +#define V(a,b,c,d) 0x##a##b##c##d +static const uint32_t RT0[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##b##c##d##a +static const uint32_t RT1[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +static const uint32_t RT2[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##d##a##b##c +static const uint32_t RT3[256] = { RT }; +#undef V + +#undef RT + +/* + * Round constants + */ +static const uint32_t RCON[10] = +{ + 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, + 0x0000001B, 0x00000036 +}; + +#else /* MBEDTLS_AES_ROM_TABLES */ + +/* + * Forward S-box & tables + */ +static unsigned char FSb[256]; +static uint32_t FT0[256]; +static uint32_t FT1[256]; +static uint32_t FT2[256]; +static uint32_t FT3[256]; + +/* + * Reverse S-box & tables + */ +static unsigned char RSb[256]; +static uint32_t RT0[256]; +static uint32_t RT1[256]; +static uint32_t RT2[256]; +static uint32_t RT3[256]; + +/* + * Round constants + */ +static uint32_t RCON[10]; + +/* + * Tables generation code + */ +#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 ) +#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) +#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 ) + +static int aes_init_done = 0; + +static void aes_gen_tables( void ) +{ + int i, x, y, z; + int pow[256]; + int log[256]; + + /* + * compute pow and log tables over GF(2^8) + */ + for( i = 0, x = 1; i < 256; i++ ) + { + pow[i] = x; + log[x] = i; + x = ( x ^ XTIME( x ) ) & 0xFF; + } + + /* + * calculate the round constants + */ + for( i = 0, x = 1; i < 10; i++ ) + { + RCON[i] = (uint32_t) x; + x = XTIME( x ) & 0xFF; + } + + /* + * generate the forward and reverse S-boxes + */ + FSb[0x00] = 0x63; + RSb[0x63] = 0x00; + + for( i = 1; i < 256; i++ ) + { + x = pow[255 - log[i]]; + + y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y ^ 0x63; + + FSb[i] = (unsigned char) x; + RSb[x] = (unsigned char) i; + } + + /* + * generate the forward and reverse tables + */ + for( i = 0; i < 256; i++ ) + { + x = FSb[i]; + y = XTIME( x ) & 0xFF; + z = ( y ^ x ) & 0xFF; + + FT0[i] = ( (uint32_t) y ) ^ + ( (uint32_t) x << 8 ) ^ + ( (uint32_t) x << 16 ) ^ + ( (uint32_t) z << 24 ); + + FT1[i] = ROTL8( FT0[i] ); + FT2[i] = ROTL8( FT1[i] ); + FT3[i] = ROTL8( FT2[i] ); + + x = RSb[i]; + + RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^ + ( (uint32_t) MUL( 0x09, x ) << 8 ) ^ + ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^ + ( (uint32_t) MUL( 0x0B, x ) << 24 ); + + RT1[i] = ROTL8( RT0[i] ); + RT2[i] = ROTL8( RT1[i] ); + RT3[i] = ROTL8( RT2[i] ); + } +} + +#endif /* MBEDTLS_AES_ROM_TABLES */ + +void mbedtls_aes_init( mbedtls_aes_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_aes_context ) ); +} + +void mbedtls_aes_free( mbedtls_aes_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_aes_context ) ); +} + +/* + * AES key schedule (encryption) + */ +#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT) +int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ) +{ + unsigned int i; + uint32_t *RK; + +#if !defined(MBEDTLS_AES_ROM_TABLES) + if( aes_init_done == 0 ) + { + aes_gen_tables(); + aes_init_done = 1; + + } +#endif + + switch( keybits ) + { + case 128: ctx->nr = 10; break; + case 192: ctx->nr = 12; break; + case 256: ctx->nr = 14; break; + default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); + } + +#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) + if( aes_padlock_ace == -1 ) + aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); + + if( aes_padlock_ace ) + ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); + else +#endif + ctx->rk = RK = ctx->buf; + +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) + return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) ); +#endif + + for( i = 0; i < ( keybits >> 5 ); i++ ) + { + GET_UINT32_LE( RK[i], key, i << 2 ); + } + + switch( ctx->nr ) + { + case 10: + + for( i = 0; i < 10; i++, RK += 4 ) + { + RK[4] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 ); + + RK[5] = RK[1] ^ RK[4]; + RK[6] = RK[2] ^ RK[5]; + RK[7] = RK[3] ^ RK[6]; + } + break; + + case 12: + + for( i = 0; i < 8; i++, RK += 6 ) + { + RK[6] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 ); + + RK[7] = RK[1] ^ RK[6]; + RK[8] = RK[2] ^ RK[7]; + RK[9] = RK[3] ^ RK[8]; + RK[10] = RK[4] ^ RK[9]; + RK[11] = RK[5] ^ RK[10]; + } + break; + + case 14: + + for( i = 0; i < 7; i++, RK += 8 ) + { + RK[8] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 ); + + RK[9] = RK[1] ^ RK[8]; + RK[10] = RK[2] ^ RK[9]; + RK[11] = RK[3] ^ RK[10]; + + RK[12] = RK[4] ^ + ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 ); + + RK[13] = RK[5] ^ RK[12]; + RK[14] = RK[6] ^ RK[13]; + RK[15] = RK[7] ^ RK[14]; + } + break; + } + + return( 0 ); +} +#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */ + +/* + * AES key schedule (decryption) + */ +#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) +int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ) +{ + int i, j, ret; + mbedtls_aes_context cty; + uint32_t *RK; + uint32_t *SK; + + mbedtls_aes_init( &cty ); + +#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) + if( aes_padlock_ace == -1 ) + aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); + + if( aes_padlock_ace ) + ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); + else +#endif + ctx->rk = RK = ctx->buf; + + /* Also checks keybits */ + if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 ) + goto exit; + + ctx->nr = cty.nr; + +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) + { + mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk, + (const unsigned char *) cty.rk, ctx->nr ); + goto exit; + } +#endif + + SK = cty.rk + cty.nr * 4; + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + + for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 ) + { + for( j = 0; j < 4; j++, SK++ ) + { + *RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^ + RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^ + RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^ + RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ]; + } + } + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + +exit: + mbedtls_aes_free( &cty ); + + return( ret ); +} +#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */ + +#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ +{ \ + X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \ + FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y3 >> 24 ) & 0xFF ]; \ + \ + X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \ + FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y0 >> 24 ) & 0xFF ]; \ + \ + X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \ + FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y1 >> 24 ) & 0xFF ]; \ + \ + X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \ + FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y2 >> 24 ) & 0xFF ]; \ +} + +#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ +{ \ + X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \ + RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y1 >> 24 ) & 0xFF ]; \ + \ + X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \ + RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y2 >> 24 ) & 0xFF ]; \ + \ + X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \ + RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y3 >> 24 ) & 0xFF ]; \ + \ + X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \ + RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y0 >> 24 ) & 0xFF ]; \ +} + +/* + * AES-ECB block encryption + */ +#if !defined(MBEDTLS_AES_ENCRYPT_ALT) +void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ) +{ + int i; + uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; + + RK = ctx->rk; + + GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; + GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; + GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; + GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; + + for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) + { + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); + } + + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + + X0 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); + + X1 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); + + X2 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); + + X3 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); + + PUT_UINT32_LE( X0, output, 0 ); + PUT_UINT32_LE( X1, output, 4 ); + PUT_UINT32_LE( X2, output, 8 ); + PUT_UINT32_LE( X3, output, 12 ); +} +#endif /* !MBEDTLS_AES_ENCRYPT_ALT */ + +/* + * AES-ECB block decryption + */ +#if !defined(MBEDTLS_AES_DECRYPT_ALT) +void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ) +{ + int i; + uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; + + RK = ctx->rk; + + GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; + GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; + GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; + GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; + + for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) + { + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); + } + + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + + X0 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); + + X1 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); + + X2 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); + + X3 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); + + PUT_UINT32_LE( X0, output, 0 ); + PUT_UINT32_LE( X1, output, 4 ); + PUT_UINT32_LE( X2, output, 8 ); + PUT_UINT32_LE( X3, output, 12 ); +} +#endif /* !MBEDTLS_AES_DECRYPT_ALT */ + +/* + * AES-ECB block encryption/decryption + */ +int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) + return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) ); +#endif + +#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) + if( aes_padlock_ace ) + { + if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 ) + return( 0 ); + + // If padlock data misaligned, we just fall back to + // unaccelerated mode + // + } +#endif + + if( mode == MBEDTLS_AES_ENCRYPT ) + mbedtls_aes_encrypt( ctx, input, output ); + else + mbedtls_aes_decrypt( ctx, input, output ); + + return( 0 ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/* + * AES-CBC buffer encryption/decryption + */ +int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int i; + unsigned char temp[16]; + + if( length % 16 ) + return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH ); + +#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) + if( aes_padlock_ace ) + { + if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 ) + return( 0 ); + + // If padlock data misaligned, we just fall back to + // unaccelerated mode + // + } +#endif + + if( mode == MBEDTLS_AES_DECRYPT ) + { + while( length > 0 ) + { + memcpy( temp, input, 16 ); + mbedtls_aes_crypt_ecb( ctx, mode, input, output ); + + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + else + { + while( length > 0 ) + { + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + mbedtls_aes_crypt_ecb( ctx, mode, output, output ); + memcpy( iv, output, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/* + * AES-CFB128 buffer encryption/decryption + */ +int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int c; + size_t n = *iv_off; + + if( mode == MBEDTLS_AES_DECRYPT ) + { + while( length-- ) + { + if( n == 0 ) + mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); + + c = *input++; + *output++ = (unsigned char)( c ^ iv[n] ); + iv[n] = (unsigned char) c; + + n = ( n + 1 ) & 0x0F; + } + } + else + { + while( length-- ) + { + if( n == 0 ) + mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); + + iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); + + n = ( n + 1 ) & 0x0F; + } + } + + *iv_off = n; + + return( 0 ); +} + +/* + * AES-CFB8 buffer encryption/decryption + */ +int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + unsigned char c; + unsigned char ov[17]; + + while( length-- ) + { + memcpy( ov, iv, 16 ); + mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); + + if( mode == MBEDTLS_AES_DECRYPT ) + ov[16] = *input; + + c = *output++ = (unsigned char)( iv[0] ^ *input++ ); + + if( mode == MBEDTLS_AES_ENCRYPT ) + ov[16] = c; + + memcpy( iv, ov + 1, 16 ); + } + + return( 0 ); +} +#endif /*MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/* + * AES-CTR buffer encryption/decryption + */ +int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ) +{ + int c, i; + size_t n = *nc_off; + + while( length-- ) + { + if( n == 0 ) { + mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block ); + + for( i = 16; i > 0; i-- ) + if( ++nonce_counter[i - 1] != 0 ) + break; + } + c = *input++; + *output++ = (unsigned char)( c ^ stream_block[n] ); + + n = ( n + 1 ) & 0x0F; + } + + *nc_off = n; + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#endif /* !MBEDTLS_AES_ALT */ + +#if defined(MBEDTLS_SELF_TEST) +/* + * AES test vectors from: + * + * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip + */ +static const unsigned char aes_test_ecb_dec[3][16] = +{ + { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58, + 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 }, + { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, + 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 }, + { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, + 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE } +}; + +static const unsigned char aes_test_ecb_enc[3][16] = +{ + { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73, + 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F }, + { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11, + 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 }, + { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D, + 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 } +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const unsigned char aes_test_cbc_dec[3][16] = +{ + { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73, + 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 }, + { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75, + 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B }, + { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75, + 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 } +}; + +static const unsigned char aes_test_cbc_enc[3][16] = +{ + { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84, + 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D }, + { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB, + 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 }, + { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5, + 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 } +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/* + * AES-CFB128 test vectors from: + * + * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + */ +static const unsigned char aes_test_cfb128_key[3][32] = +{ + { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, + { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, + 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, + 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, + { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } +}; + +static const unsigned char aes_test_cfb128_iv[16] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; + +static const unsigned char aes_test_cfb128_pt[64] = +{ + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const unsigned char aes_test_cfb128_ct[3][64] = +{ + { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, + 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, + 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F, + 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B, + 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40, + 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF, + 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E, + 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 }, + { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, + 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, + 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21, + 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A, + 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1, + 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9, + 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0, + 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF }, + { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, + 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, + 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8, + 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B, + 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92, + 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9, + 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8, + 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 } +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/* + * AES-CTR test vectors from: + * + * http://www.faqs.org/rfcs/rfc3686.html + */ + +static const unsigned char aes_test_ctr_key[3][16] = +{ + { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, + 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, + { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, + 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, + { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } +}; + +static const unsigned char aes_test_ctr_nonce_counter[3][16] = +{ + { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, + 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, + 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } +}; + +static const unsigned char aes_test_ctr_pt[3][48] = +{ + { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23 } +}; + +static const unsigned char aes_test_ctr_ct[3][48] = +{ + { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, + 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 }, + { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, + 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, + 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, + 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 }, + { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, + 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, + 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, + 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, + 0x25, 0xB2, 0x07, 0x2F } +}; + +static const int aes_test_ctr_len[3] = + { 16, 32, 36 }; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +/* + * Checkup routine + */ +int mbedtls_aes_self_test( int verbose ) +{ + int ret = 0, i, j, u, v; + unsigned char key[32]; + unsigned char buf[64]; +#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) + unsigned char iv[16]; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CBC) + unsigned char prv[16]; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) + size_t offset; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + int len; + unsigned char nonce_counter[16]; + unsigned char stream_block[16]; +#endif + mbedtls_aes_context ctx; + + memset( key, 0, 32 ); + mbedtls_aes_init( &ctx ); + + /* + * ECB mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-ECB-%3d (%s): ", 128 + u * 64, + ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memset( buf, 0, 16 ); + + if( v == MBEDTLS_AES_DECRYPT ) + { + mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + mbedtls_aes_crypt_ecb( &ctx, v, buf, buf ); + + if( memcmp( buf, aes_test_ecb_dec[u], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + mbedtls_aes_crypt_ecb( &ctx, v, buf, buf ); + + if( memcmp( buf, aes_test_ecb_enc[u], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + /* + * CBC mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-CBC-%3d (%s): ", 128 + u * 64, + ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memset( iv , 0, 16 ); + memset( prv, 0, 16 ); + memset( buf, 0, 16 ); + + if( v == MBEDTLS_AES_DECRYPT ) + { + mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); + + if( memcmp( buf, aes_test_cbc_dec[u], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + { + unsigned char tmp[16]; + + mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); + + memcpy( tmp, prv, 16 ); + memcpy( prv, buf, 16 ); + memcpy( buf, tmp, 16 ); + } + + if( memcmp( prv, aes_test_cbc_enc[u], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) + /* + * CFB128 mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-CFB128-%3d (%s): ", 128 + u * 64, + ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( iv, aes_test_cfb128_iv, 16 ); + memcpy( key, aes_test_cfb128_key[u], 16 + u * 8 ); + + offset = 0; + mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + if( v == MBEDTLS_AES_DECRYPT ) + { + memcpy( buf, aes_test_cfb128_ct[u], 64 ); + mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); + + if( memcmp( buf, aes_test_cfb128_pt, 64 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + memcpy( buf, aes_test_cfb128_pt, 64 ); + mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); + + if( memcmp( buf, aes_test_cfb128_ct[u], 64 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) + /* + * CTR mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-CTR-128 (%s): ", + ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); + memcpy( key, aes_test_ctr_key[u], 16 ); + + offset = 0; + mbedtls_aes_setkey_enc( &ctx, key, 128 ); + + if( v == MBEDTLS_AES_DECRYPT ) + { + len = aes_test_ctr_len[u]; + memcpy( buf, aes_test_ctr_ct[u], len ); + + mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, aes_test_ctr_pt[u], len ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + len = aes_test_ctr_len[u]; + memcpy( buf, aes_test_ctr_pt[u], len ); + + mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, aes_test_ctr_ct[u], len ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + + ret = 0; + +exit: + mbedtls_aes_free( &ctx ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_AES_C */ diff --git a/lib/mbedtls/src/ccm.c b/lib/mbedtls/src/ccm.c new file mode 100644 index 000000000..13a8fd1a2 --- /dev/null +++ b/lib/mbedtls/src/ccm.c @@ -0,0 +1,464 @@ +/* + * NIST SP800-38C compliant CCM implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * Definition of CCM: + * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf + * RFC 3610 "Counter with CBC-MAC (CCM)" + * + * Related: + * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CCM_C) + +#include "mbedtls/ccm.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +#define CCM_ENCRYPT 0 +#define CCM_DECRYPT 1 + +/* + * Initialize context + */ +void mbedtls_ccm_init( mbedtls_ccm_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_ccm_context ) ); +} + +int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits ) +{ + int ret; + const mbedtls_cipher_info_t *cipher_info; + + cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB ); + if( cipher_info == NULL ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + if( cipher_info->block_size != 16 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + mbedtls_cipher_free( &ctx->cipher_ctx ); + + if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, + MBEDTLS_ENCRYPT ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} + +/* + * Free context + */ +void mbedtls_ccm_free( mbedtls_ccm_context *ctx ) +{ + mbedtls_cipher_free( &ctx->cipher_ctx ); + mbedtls_zeroize( ctx, sizeof( mbedtls_ccm_context ) ); +} + +/* + * Macros for common operations. + * Results in smaller compiled code than static inline functions. + */ + +/* + * Update the CBC-MAC state in y using a block in b + * (Always using b as the source helps the compiler optimise a bit better.) + */ +#define UPDATE_CBC_MAC \ + for( i = 0; i < 16; i++ ) \ + y[i] ^= b[i]; \ + \ + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \ + return( ret ); + +/* + * Encrypt or decrypt a partial block with CTR + * Warning: using b for temporary storage! src and dst must not be b! + * This avoids allocating one more 16 bytes buffer while allowing src == dst. + */ +#define CTR_CRYPT( dst, src, len ) \ + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, 16, b, &olen ) ) != 0 ) \ + return( ret ); \ + \ + for( i = 0; i < len; i++ ) \ + dst[i] = src[i] ^ b[i]; + +/* + * Authenticated encryption or decryption + */ +static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ) +{ + int ret; + unsigned char i; + unsigned char q; + size_t len_left, olen; + unsigned char b[16]; + unsigned char y[16]; + unsigned char ctr[16]; + const unsigned char *src; + unsigned char *dst; + + /* + * Check length requirements: SP800-38C A.1 + * Additional requirement: a < 2^16 - 2^8 to simplify the code. + * 'length' checked later (when writing it to the first block) + */ + if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + /* Also implies q is within bounds */ + if( iv_len < 7 || iv_len > 13 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + if( add_len > 0xFF00 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + q = 16 - 1 - (unsigned char) iv_len; + + /* + * First block B_0: + * 0 .. 0 flags + * 1 .. iv_len nonce (aka iv) + * iv_len+1 .. 15 length + * + * With flags as (bits): + * 7 0 + * 6 add present? + * 5 .. 3 (t - 2) / 2 + * 2 .. 0 q - 1 + */ + b[0] = 0; + b[0] |= ( add_len > 0 ) << 6; + b[0] |= ( ( tag_len - 2 ) / 2 ) << 3; + b[0] |= q - 1; + + memcpy( b + 1, iv, iv_len ); + + for( i = 0, len_left = length; i < q; i++, len_left >>= 8 ) + b[15-i] = (unsigned char)( len_left & 0xFF ); + + if( len_left > 0 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + + /* Start CBC-MAC with first block */ + memset( y, 0, 16 ); + UPDATE_CBC_MAC; + + /* + * If there is additional data, update CBC-MAC with + * add_len, add, 0 (padding to a block boundary) + */ + if( add_len > 0 ) + { + size_t use_len; + len_left = add_len; + src = add; + + memset( b, 0, 16 ); + b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF ); + b[1] = (unsigned char)( ( add_len ) & 0xFF ); + + use_len = len_left < 16 - 2 ? len_left : 16 - 2; + memcpy( b + 2, src, use_len ); + len_left -= use_len; + src += use_len; + + UPDATE_CBC_MAC; + + while( len_left > 0 ) + { + use_len = len_left > 16 ? 16 : len_left; + + memset( b, 0, 16 ); + memcpy( b, src, use_len ); + UPDATE_CBC_MAC; + + len_left -= use_len; + src += use_len; + } + } + + /* + * Prepare counter block for encryption: + * 0 .. 0 flags + * 1 .. iv_len nonce (aka iv) + * iv_len+1 .. 15 counter (initially 1) + * + * With flags as (bits): + * 7 .. 3 0 + * 2 .. 0 q - 1 + */ + ctr[0] = q - 1; + memcpy( ctr + 1, iv, iv_len ); + memset( ctr + 1 + iv_len, 0, q ); + ctr[15] = 1; + + /* + * Authenticate and {en,de}crypt the message. + * + * The only difference between encryption and decryption is + * the respective order of authentication and {en,de}cryption. + */ + len_left = length; + src = input; + dst = output; + + while( len_left > 0 ) + { + size_t use_len = len_left > 16 ? 16 : len_left; + + if( mode == CCM_ENCRYPT ) + { + memset( b, 0, 16 ); + memcpy( b, src, use_len ); + UPDATE_CBC_MAC; + } + + CTR_CRYPT( dst, src, use_len ); + + if( mode == CCM_DECRYPT ) + { + memset( b, 0, 16 ); + memcpy( b, dst, use_len ); + UPDATE_CBC_MAC; + } + + dst += use_len; + src += use_len; + len_left -= use_len; + + /* + * Increment counter. + * No need to check for overflow thanks to the length check above. + */ + for( i = 0; i < q; i++ ) + if( ++ctr[15-i] != 0 ) + break; + } + + /* + * Authentication: reset counter and crypt/mask internal tag + */ + for( i = 0; i < q; i++ ) + ctr[15-i] = 0; + + CTR_CRYPT( y, y, 16 ); + memcpy( tag, y, tag_len ); + + return( 0 ); +} + +/* + * Authenticated encryption + */ +int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ) +{ + return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len, + add, add_len, input, output, tag, tag_len ) ); +} + +/* + * Authenticated decryption + */ +int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len ) +{ + int ret; + unsigned char check_tag[16]; + unsigned char i; + int diff; + + if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length, + iv, iv_len, add, add_len, + input, output, check_tag, tag_len ) ) != 0 ) + { + return( ret ); + } + + /* Check tag in "constant-time" */ + for( diff = 0, i = 0; i < tag_len; i++ ) + diff |= tag[i] ^ check_tag[i]; + + if( diff != 0 ) + { + mbedtls_zeroize( output, length ); + return( MBEDTLS_ERR_CCM_AUTH_FAILED ); + } + + return( 0 ); +} + + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +/* + * Examples 1 to 3 from SP800-38C Appendix C + */ + +#define NB_TESTS 3 + +/* + * The data is the same for all tests, only the used length changes + */ +static const unsigned char key[] = { + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f +}; + +static const unsigned char iv[] = { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b +}; + +static const unsigned char ad[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13 +}; + +static const unsigned char msg[] = { + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +}; + +static const size_t iv_len [NB_TESTS] = { 7, 8, 12 }; +static const size_t add_len[NB_TESTS] = { 8, 16, 20 }; +static const size_t msg_len[NB_TESTS] = { 4, 16, 24 }; +static const size_t tag_len[NB_TESTS] = { 4, 6, 8 }; + +static const unsigned char res[NB_TESTS][32] = { + { 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d }, + { 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, + 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d, + 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd }, + { 0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a, + 0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b, + 0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5, + 0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 } +}; + +int mbedtls_ccm_self_test( int verbose ) +{ + mbedtls_ccm_context ctx; + unsigned char out[32]; + size_t i; + int ret; + + mbedtls_ccm_init( &ctx ); + + if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( " CCM: setup failed" ); + + return( 1 ); + } + + for( i = 0; i < NB_TESTS; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " CCM-AES #%u: ", (unsigned int) i + 1 ); + + ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i], + iv, iv_len[i], ad, add_len[i], + msg, out, + out + msg_len[i], tag_len[i] ); + + if( ret != 0 || + memcmp( out, res[i], msg_len[i] + tag_len[i] ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i], + iv, iv_len[i], ad, add_len[i], + res[i], out, + res[i] + msg_len[i], tag_len[i] ); + + if( ret != 0 || + memcmp( out, msg, msg_len[i] ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + mbedtls_ccm_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#endif /* MBEDTLS_CCM_C */ diff --git a/lib/mbedtls/src/cipher.c b/lib/mbedtls/src/cipher.c new file mode 100644 index 000000000..a88343869 --- /dev/null +++ b/lib/mbedtls/src/cipher.c @@ -0,0 +1,917 @@ +/** + * \file cipher.c + * + * \brief Generic cipher wrapper for mbed TLS + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CIPHER_C) + +#include "mbedtls/cipher.h" +#include "mbedtls/cipher_internal.h" + +#include +#include + +#if defined(MBEDTLS_GCM_C) +#include "mbedtls/gcm.h" +#endif + +#if defined(MBEDTLS_CCM_C) +#include "mbedtls/ccm.h" +#endif + +#if defined(MBEDTLS_CMAC_C) +#include "mbedtls/cmac.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) +#define MBEDTLS_CIPHER_MODE_STREAM +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +static int supported_init = 0; + +const int *mbedtls_cipher_list( void ) +{ + const mbedtls_cipher_definition_t *def; + int *type; + + if( ! supported_init ) + { + def = mbedtls_cipher_definitions; + type = mbedtls_cipher_supported; + + while( def->type != 0 ) + *type++ = (*def++).type; + + *type = 0; + + supported_init = 1; + } + + return( mbedtls_cipher_supported ); +} + +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ) +{ + const mbedtls_cipher_definition_t *def; + + for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) + if( def->type == cipher_type ) + return( def->info ); + + return( NULL ); +} + +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ) +{ + const mbedtls_cipher_definition_t *def; + + if( NULL == cipher_name ) + return( NULL ); + + for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) + if( ! strcmp( def->info->name, cipher_name ) ) + return( def->info ); + + return( NULL ); +} + +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, + int key_bitlen, + const mbedtls_cipher_mode_t mode ) +{ + const mbedtls_cipher_definition_t *def; + + for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) + if( def->info->base->cipher == cipher_id && + def->info->key_bitlen == (unsigned) key_bitlen && + def->info->mode == mode ) + return( def->info ); + + return( NULL ); +} + +void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); +} + +void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ) +{ + if( ctx == NULL ) + return; + +#if defined(MBEDTLS_CMAC_C) + if( ctx->cmac_ctx ) + { + mbedtls_zeroize( ctx->cmac_ctx, sizeof( mbedtls_cmac_context_t ) ); + mbedtls_free( ctx->cmac_ctx ); + } +#endif + + if( ctx->cipher_ctx ) + ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); + + mbedtls_zeroize( ctx, sizeof(mbedtls_cipher_context_t) ); +} + +int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info ) +{ + if( NULL == cipher_info || NULL == ctx ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); + + if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) ) + return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); + + ctx->cipher_info = cipher_info; + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) + /* + * Ignore possible errors caused by a cipher mode that doesn't use padding + */ +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) + (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 ); +#else + (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE ); +#endif +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + + return( 0 ); +} + +int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key, + int key_bitlen, const mbedtls_operation_t operation ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 && + (int) ctx->cipher_info->key_bitlen != key_bitlen ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + ctx->key_bitlen = key_bitlen; + ctx->operation = operation; + + /* + * For CFB and CTR mode always use the encryption key schedule + */ + if( MBEDTLS_ENCRYPT == operation || + MBEDTLS_MODE_CFB == ctx->cipher_info->mode || + MBEDTLS_MODE_CTR == ctx->cipher_info->mode ) + { + return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key, + ctx->key_bitlen ); + } + + if( MBEDTLS_DECRYPT == operation ) + return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key, + ctx->key_bitlen ); + + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); +} + +int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len ) +{ + size_t actual_iv_size; + + if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + /* avoid buffer overflow in ctx->iv */ + if( iv_len > MBEDTLS_MAX_IV_LENGTH ) + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + + if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 ) + actual_iv_size = iv_len; + else + { + actual_iv_size = ctx->cipher_info->iv_size; + + /* avoid reading past the end of input buffer */ + if( actual_iv_size > iv_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + memcpy( ctx->iv, iv, actual_iv_size ); + ctx->iv_size = actual_iv_size; + + return( 0 ); +} + +int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + ctx->unprocessed_len = 0; + + return( 0 ); +} + +#if defined(MBEDTLS_GCM_C) +int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, + const unsigned char *ad, size_t ad_len ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + { + return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation, + ctx->iv, ctx->iv_size, ad, ad_len ); + } + + return( 0 ); +} +#endif /* MBEDTLS_GCM_C */ + +int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, + size_t ilen, unsigned char *output, size_t *olen ) +{ + int ret; + size_t block_size = 0; + + if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + *olen = 0; + block_size = mbedtls_cipher_get_block_size( ctx ); + + if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) + { + if( ilen != block_size ) + return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + + *olen = ilen; + + if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx, + ctx->operation, input, output ) ) ) + { + return( ret ); + } + + return( 0 ); + } + +#if defined(MBEDTLS_GCM_C) + if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM ) + { + *olen = ilen; + return mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input, + output ); + } +#endif + + if ( 0 == block_size ) + { + return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; + } + + if( input == output && + ( ctx->unprocessed_len != 0 || ilen % block_size ) ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC ) + { + size_t copy_len = 0; + + /* + * If there is not enough data for a full block, cache it. + */ + if( ( ctx->operation == MBEDTLS_DECRYPT && + ilen + ctx->unprocessed_len <= block_size ) || + ( ctx->operation == MBEDTLS_ENCRYPT && + ilen + ctx->unprocessed_len < block_size ) ) + { + memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, + ilen ); + + ctx->unprocessed_len += ilen; + return( 0 ); + } + + /* + * Process cached data first + */ + if( 0 != ctx->unprocessed_len ) + { + copy_len = block_size - ctx->unprocessed_len; + + memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, + copy_len ); + + if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, + ctx->operation, block_size, ctx->iv, + ctx->unprocessed_data, output ) ) ) + { + return( ret ); + } + + *olen += block_size; + output += block_size; + ctx->unprocessed_len = 0; + + input += copy_len; + ilen -= copy_len; + } + + /* + * Cache final, incomplete block + */ + if( 0 != ilen ) + { + if( 0 == block_size ) + { + return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; + } + + copy_len = ilen % block_size; + if( copy_len == 0 && ctx->operation == MBEDTLS_DECRYPT ) + copy_len = block_size; + + memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), + copy_len ); + + ctx->unprocessed_len += copy_len; + ilen -= copy_len; + } + + /* + * Process remaining full blocks + */ + if( ilen ) + { + if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, + ctx->operation, ilen, ctx->iv, input, output ) ) ) + { + return( ret ); + } + + *olen += ilen; + } + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) + if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB ) + { + if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx, + ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv, + input, output ) ) ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) + if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR ) + { + if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx, + ilen, &ctx->unprocessed_len, ctx->iv, + ctx->unprocessed_data, input, output ) ) ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM ) + { + if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx, + ilen, input, output ) ) ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_STREAM */ + + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) +/* + * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len + */ +static void add_pkcs_padding( unsigned char *output, size_t output_len, + size_t data_len ) +{ + size_t padding_len = output_len - data_len; + unsigned char i; + + for( i = 0; i < padding_len; i++ ) + output[data_len + i] = (unsigned char) padding_len; +} + +static int get_pkcs_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i, pad_idx; + unsigned char padding_len, bad = 0; + + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + padding_len = input[input_len - 1]; + *data_len = input_len - padding_len; + + /* Avoid logical || since it results in a branch */ + bad |= padding_len > input_len; + bad |= padding_len == 0; + + /* The number of bytes checked must be independent of padding_len, + * so pick input_len, which is usually 8 or 16 (one block) */ + pad_idx = input_len - padding_len; + for( i = 0; i < input_len; i++ ) + bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx ); + + return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); +} +#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ + +#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) +/* + * One and zeros padding: fill with 80 00 ... 00 + */ +static void add_one_and_zeros_padding( unsigned char *output, + size_t output_len, size_t data_len ) +{ + size_t padding_len = output_len - data_len; + unsigned char i = 0; + + output[data_len] = 0x80; + for( i = 1; i < padding_len; i++ ) + output[data_len + i] = 0x00; +} + +static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i; + unsigned char done = 0, prev_done, bad; + + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + bad = 0xFF; + *data_len = 0; + for( i = input_len; i > 0; i-- ) + { + prev_done = done; + done |= ( input[i-1] != 0 ); + *data_len |= ( i - 1 ) * ( done != prev_done ); + bad &= ( input[i-1] ^ 0x80 ) | ( done == prev_done ); + } + + return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); + +} +#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ + +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) +/* + * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length + */ +static void add_zeros_and_len_padding( unsigned char *output, + size_t output_len, size_t data_len ) +{ + size_t padding_len = output_len - data_len; + unsigned char i = 0; + + for( i = 1; i < padding_len; i++ ) + output[data_len + i - 1] = 0x00; + output[output_len - 1] = (unsigned char) padding_len; +} + +static int get_zeros_and_len_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i, pad_idx; + unsigned char padding_len, bad = 0; + + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + padding_len = input[input_len - 1]; + *data_len = input_len - padding_len; + + /* Avoid logical || since it results in a branch */ + bad |= padding_len > input_len; + bad |= padding_len == 0; + + /* The number of bytes checked must be independent of padding_len */ + pad_idx = input_len - padding_len; + for( i = 0; i < input_len - 1; i++ ) + bad |= input[i] * ( i >= pad_idx ); + + return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); +} +#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ + +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) +/* + * Zero padding: fill with 00 ... 00 + */ +static void add_zeros_padding( unsigned char *output, + size_t output_len, size_t data_len ) +{ + size_t i; + + for( i = data_len; i < output_len; i++ ) + output[i] = 0x00; +} + +static int get_zeros_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i; + unsigned char done = 0, prev_done; + + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + *data_len = 0; + for( i = input_len; i > 0; i-- ) + { + prev_done = done; + done |= ( input[i-1] != 0 ); + *data_len |= i * ( done != prev_done ); + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ + +/* + * No padding: don't pad :) + * + * There is no add_padding function (check for NULL in mbedtls_cipher_finish) + * but a trivial get_padding function + */ +static int get_no_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + *data_len = input_len; + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + +int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, + unsigned char *output, size_t *olen ) +{ + if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + *olen = 0; + + if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode || + MBEDTLS_MODE_CTR == ctx->cipher_info->mode || + MBEDTLS_MODE_GCM == ctx->cipher_info->mode || + MBEDTLS_MODE_STREAM == ctx->cipher_info->mode ) + { + return( 0 ); + } + + if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode ) + { + if( ctx->unprocessed_len != 0 ) + return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + + return( 0 ); + } + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode ) + { + int ret = 0; + + if( MBEDTLS_ENCRYPT == ctx->operation ) + { + /* check for 'no padding' mode */ + if( NULL == ctx->add_padding ) + { + if( 0 != ctx->unprocessed_len ) + return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + + return( 0 ); + } + + ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ), + ctx->unprocessed_len ); + } + else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len ) + { + /* + * For decrypt operations, expect a full block, + * or an empty block if no padding + */ + if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len ) + return( 0 ); + + return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + } + + /* cipher block */ + if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, + ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv, + ctx->unprocessed_data, output ) ) ) + { + return( ret ); + } + + /* Set output size for decryption */ + if( MBEDTLS_DECRYPT == ctx->operation ) + return ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ), + olen ); + + /* Set output size for encryption */ + *olen = mbedtls_cipher_get_block_size( ctx ); + return( 0 ); + } +#else + ((void) output); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) +int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode ) +{ + if( NULL == ctx || + MBEDTLS_MODE_CBC != ctx->cipher_info->mode ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + switch( mode ) + { +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) + case MBEDTLS_PADDING_PKCS7: + ctx->add_padding = add_pkcs_padding; + ctx->get_padding = get_pkcs_padding; + break; +#endif +#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) + case MBEDTLS_PADDING_ONE_AND_ZEROS: + ctx->add_padding = add_one_and_zeros_padding; + ctx->get_padding = get_one_and_zeros_padding; + break; +#endif +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) + case MBEDTLS_PADDING_ZEROS_AND_LEN: + ctx->add_padding = add_zeros_and_len_padding; + ctx->get_padding = get_zeros_and_len_padding; + break; +#endif +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) + case MBEDTLS_PADDING_ZEROS: + ctx->add_padding = add_zeros_padding; + ctx->get_padding = get_zeros_padding; + break; +#endif + case MBEDTLS_PADDING_NONE: + ctx->add_padding = NULL; + ctx->get_padding = get_no_padding; + break; + + default: + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + +#if defined(MBEDTLS_GCM_C) +int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, + unsigned char *tag, size_t tag_len ) +{ + if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( MBEDTLS_ENCRYPT != ctx->operation ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len ); + + return( 0 ); +} + +int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, + const unsigned char *tag, size_t tag_len ) +{ + int ret; + + if( NULL == ctx || NULL == ctx->cipher_info || + MBEDTLS_DECRYPT != ctx->operation ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + { + unsigned char check_tag[16]; + size_t i; + int diff; + + if( tag_len > sizeof( check_tag ) ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, + check_tag, tag_len ) ) ) + { + return( ret ); + } + + /* Check the tag in "constant-time" */ + for( diff = 0, i = 0; i < tag_len; i++ ) + diff |= tag[i] ^ check_tag[i]; + + if( diff != 0 ) + return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); + + return( 0 ); + } + + return( 0 ); +} +#endif /* MBEDTLS_GCM_C */ + +/* + * Packet-oriented wrapper for non-AEAD modes + */ +int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen ) +{ + int ret; + size_t finish_olen; + + if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 ) + return( ret ); + + *olen += finish_olen; + + return( 0 ); +} + +#if defined(MBEDTLS_CIPHER_MODE_AEAD) +/* + * Packet-oriented encryption for AEAD modes + */ +int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + unsigned char *tag, size_t tag_len ) +{ +#if defined(MBEDTLS_GCM_C) + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + { + *olen = ilen; + return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen, + iv, iv_len, ad, ad_len, input, output, + tag_len, tag ) ); + } +#endif /* MBEDTLS_GCM_C */ +#if defined(MBEDTLS_CCM_C) + if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) + { + *olen = ilen; + return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, input, output, + tag, tag_len ) ); + } +#endif /* MBEDTLS_CCM_C */ + + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} + +/* + * Packet-oriented decryption for AEAD modes + */ +int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + const unsigned char *tag, size_t tag_len ) +{ +#if defined(MBEDTLS_GCM_C) + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + { + int ret; + + *olen = ilen; + ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, + tag, tag_len, input, output ); + + if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED ) + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + + return( ret ); + } +#endif /* MBEDTLS_GCM_C */ +#if defined(MBEDTLS_CCM_C) + if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) + { + int ret; + + *olen = ilen; + ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, + input, output, tag, tag_len ); + + if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED ) + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + + return( ret ); + } +#endif /* MBEDTLS_CCM_C */ + + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} +#endif /* MBEDTLS_CIPHER_MODE_AEAD */ + +#endif /* MBEDTLS_CIPHER_C */ diff --git a/lib/mbedtls/src/cipher_wrap.c b/lib/mbedtls/src/cipher_wrap.c new file mode 100644 index 000000000..dc76af8ff --- /dev/null +++ b/lib/mbedtls/src/cipher_wrap.c @@ -0,0 +1,1451 @@ +/** + * \file cipher_wrap.c + * + * \brief Generic cipher wrapper for mbed TLS + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CIPHER_C) + +#include "mbedtls/cipher_internal.h" + +#if defined(MBEDTLS_AES_C) +#include "mbedtls/aes.h" +#endif + +#if defined(MBEDTLS_ARC4_C) +#include "mbedtls/arc4.h" +#endif + +#if defined(MBEDTLS_CAMELLIA_C) +#include "mbedtls/camellia.h" +#endif + +#if defined(MBEDTLS_DES_C) +#include "mbedtls/des.h" +#endif + +#if defined(MBEDTLS_BLOWFISH_C) +#include "mbedtls/blowfish.h" +#endif + +#if defined(MBEDTLS_GCM_C) +#include "mbedtls/gcm.h" +#endif + +#if defined(MBEDTLS_CCM_C) +#include "mbedtls/ccm.h" +#endif + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +#include +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#if defined(MBEDTLS_GCM_C) +/* shared by all GCM ciphers */ +static void *gcm_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_gcm_context ) ); + + if( ctx != NULL ) + mbedtls_gcm_init( (mbedtls_gcm_context *) ctx ); + + return( ctx ); +} + +static void gcm_ctx_free( void *ctx ) +{ + mbedtls_gcm_free( ctx ); + mbedtls_free( ctx ); +} +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +/* shared by all CCM ciphers */ +static void *ccm_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ccm_context ) ); + + if( ctx != NULL ) + mbedtls_ccm_init( (mbedtls_ccm_context *) ctx ); + + return( ctx ); +} + +static void ccm_ctx_free( void *ctx ) +{ + mbedtls_ccm_free( ctx ); + mbedtls_free( ctx ); +} +#endif /* MBEDTLS_CCM_C */ + +#if defined(MBEDTLS_AES_C) + +static int aes_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_ecb( (mbedtls_aes_context *) ctx, operation, input, output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int aes_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_cbc( (mbedtls_aes_context *) ctx, operation, length, iv, input, + output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int aes_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_cfb128( (mbedtls_aes_context *) ctx, operation, length, iv_off, iv, + input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_ctr( (mbedtls_aes_context *) ctx, length, nc_off, nonce_counter, + stream_block, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_aes_setkey_dec( (mbedtls_aes_context *) ctx, key, key_bitlen ); +} + +static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_aes_setkey_enc( (mbedtls_aes_context *) ctx, key, key_bitlen ); +} + +static void * aes_ctx_alloc( void ) +{ + mbedtls_aes_context *aes = mbedtls_calloc( 1, sizeof( mbedtls_aes_context ) ); + + if( aes == NULL ) + return( NULL ); + + mbedtls_aes_init( aes ); + + return( aes ); +} + +static void aes_ctx_free( void *ctx ) +{ + mbedtls_aes_free( (mbedtls_aes_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t aes_info = { + MBEDTLS_CIPHER_ID_AES, + aes_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + aes_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + aes_crypt_cfb128_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + aes_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + aes_setkey_enc_wrap, + aes_setkey_dec_wrap, + aes_ctx_alloc, + aes_ctx_free +}; + +static const mbedtls_cipher_info_t aes_128_ecb_info = { + MBEDTLS_CIPHER_AES_128_ECB, + MBEDTLS_MODE_ECB, + 128, + "AES-128-ECB", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_ecb_info = { + MBEDTLS_CIPHER_AES_192_ECB, + MBEDTLS_MODE_ECB, + 192, + "AES-192-ECB", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_ecb_info = { + MBEDTLS_CIPHER_AES_256_ECB, + MBEDTLS_MODE_ECB, + 256, + "AES-256-ECB", + 16, + 0, + 16, + &aes_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t aes_128_cbc_info = { + MBEDTLS_CIPHER_AES_128_CBC, + MBEDTLS_MODE_CBC, + 128, + "AES-128-CBC", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_cbc_info = { + MBEDTLS_CIPHER_AES_192_CBC, + MBEDTLS_MODE_CBC, + 192, + "AES-192-CBC", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_cbc_info = { + MBEDTLS_CIPHER_AES_256_CBC, + MBEDTLS_MODE_CBC, + 256, + "AES-256-CBC", + 16, + 0, + 16, + &aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t aes_128_cfb128_info = { + MBEDTLS_CIPHER_AES_128_CFB128, + MBEDTLS_MODE_CFB, + 128, + "AES-128-CFB128", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_cfb128_info = { + MBEDTLS_CIPHER_AES_192_CFB128, + MBEDTLS_MODE_CFB, + 192, + "AES-192-CFB128", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_cfb128_info = { + MBEDTLS_CIPHER_AES_256_CFB128, + MBEDTLS_MODE_CFB, + 256, + "AES-256-CFB128", + 16, + 0, + 16, + &aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t aes_128_ctr_info = { + MBEDTLS_CIPHER_AES_128_CTR, + MBEDTLS_MODE_CTR, + 128, + "AES-128-CTR", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_ctr_info = { + MBEDTLS_CIPHER_AES_192_CTR, + MBEDTLS_MODE_CTR, + 192, + "AES-192-CTR", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_ctr_info = { + MBEDTLS_CIPHER_AES_256_CTR, + MBEDTLS_MODE_CTR, + 256, + "AES-256-CTR", + 16, + 0, + 16, + &aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_GCM_C) +static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_AES, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t gcm_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + gcm_aes_setkey_wrap, + gcm_aes_setkey_wrap, + gcm_ctx_alloc, + gcm_ctx_free, +}; + +static const mbedtls_cipher_info_t aes_128_gcm_info = { + MBEDTLS_CIPHER_AES_128_GCM, + MBEDTLS_MODE_GCM, + 128, + "AES-128-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; + +static const mbedtls_cipher_info_t aes_192_gcm_info = { + MBEDTLS_CIPHER_AES_192_GCM, + MBEDTLS_MODE_GCM, + 192, + "AES-192-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; + +static const mbedtls_cipher_info_t aes_256_gcm_info = { + MBEDTLS_CIPHER_AES_256_GCM, + MBEDTLS_MODE_GCM, + 256, + "AES-256-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +static int ccm_aes_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_AES, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t ccm_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + ccm_aes_setkey_wrap, + ccm_aes_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +static const mbedtls_cipher_info_t aes_128_ccm_info = { + MBEDTLS_CIPHER_AES_128_CCM, + MBEDTLS_MODE_CCM, + 128, + "AES-128-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; + +static const mbedtls_cipher_info_t aes_192_ccm_info = { + MBEDTLS_CIPHER_AES_192_CCM, + MBEDTLS_MODE_CCM, + 192, + "AES-192-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; + +static const mbedtls_cipher_info_t aes_256_ccm_info = { + MBEDTLS_CIPHER_AES_256_CCM, + MBEDTLS_MODE_CCM, + 256, + "AES-256-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; +#endif /* MBEDTLS_CCM_C */ + +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) + +static int camellia_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_ecb( (mbedtls_camellia_context *) ctx, operation, input, + output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int camellia_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_cbc( (mbedtls_camellia_context *) ctx, operation, length, iv, + input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int camellia_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_cfb128( (mbedtls_camellia_context *) ctx, operation, length, + iv_off, iv, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int camellia_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_ctr( (mbedtls_camellia_context *) ctx, length, nc_off, + nonce_counter, stream_block, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_camellia_setkey_dec( (mbedtls_camellia_context *) ctx, key, key_bitlen ); +} + +static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_camellia_setkey_enc( (mbedtls_camellia_context *) ctx, key, key_bitlen ); +} + +static void * camellia_ctx_alloc( void ) +{ + mbedtls_camellia_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_camellia_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_camellia_init( ctx ); + + return( ctx ); +} + +static void camellia_ctx_free( void *ctx ) +{ + mbedtls_camellia_free( (mbedtls_camellia_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + camellia_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + camellia_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + camellia_crypt_cfb128_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + camellia_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + camellia_setkey_enc_wrap, + camellia_setkey_dec_wrap, + camellia_ctx_alloc, + camellia_ctx_free +}; + +static const mbedtls_cipher_info_t camellia_128_ecb_info = { + MBEDTLS_CIPHER_CAMELLIA_128_ECB, + MBEDTLS_MODE_ECB, + 128, + "CAMELLIA-128-ECB", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_ecb_info = { + MBEDTLS_CIPHER_CAMELLIA_192_ECB, + MBEDTLS_MODE_ECB, + 192, + "CAMELLIA-192-ECB", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_ecb_info = { + MBEDTLS_CIPHER_CAMELLIA_256_ECB, + MBEDTLS_MODE_ECB, + 256, + "CAMELLIA-256-ECB", + 16, + 0, + 16, + &camellia_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t camellia_128_cbc_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CBC, + MBEDTLS_MODE_CBC, + 128, + "CAMELLIA-128-CBC", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_cbc_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CBC, + MBEDTLS_MODE_CBC, + 192, + "CAMELLIA-192-CBC", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_cbc_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CBC, + MBEDTLS_MODE_CBC, + 256, + "CAMELLIA-256-CBC", + 16, + 0, + 16, + &camellia_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t camellia_128_cfb128_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CFB128, + MBEDTLS_MODE_CFB, + 128, + "CAMELLIA-128-CFB128", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_cfb128_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CFB128, + MBEDTLS_MODE_CFB, + 192, + "CAMELLIA-192-CFB128", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_cfb128_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CFB128, + MBEDTLS_MODE_CFB, + 256, + "CAMELLIA-256-CFB128", + 16, + 0, + 16, + &camellia_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t camellia_128_ctr_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CTR, + MBEDTLS_MODE_CTR, + 128, + "CAMELLIA-128-CTR", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_ctr_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CTR, + MBEDTLS_MODE_CTR, + 192, + "CAMELLIA-192-CTR", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_ctr_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CTR, + MBEDTLS_MODE_CTR, + 256, + "CAMELLIA-256-CTR", + 16, + 0, + 16, + &camellia_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_GCM_C) +static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t gcm_camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + gcm_camellia_setkey_wrap, + gcm_camellia_setkey_wrap, + gcm_ctx_alloc, + gcm_ctx_free, +}; + +static const mbedtls_cipher_info_t camellia_128_gcm_info = { + MBEDTLS_CIPHER_CAMELLIA_128_GCM, + MBEDTLS_MODE_GCM, + 128, + "CAMELLIA-128-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_gcm_info = { + MBEDTLS_CIPHER_CAMELLIA_192_GCM, + MBEDTLS_MODE_GCM, + 192, + "CAMELLIA-192-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_gcm_info = { + MBEDTLS_CIPHER_CAMELLIA_256_GCM, + MBEDTLS_MODE_GCM, + 256, + "CAMELLIA-256-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +static int ccm_camellia_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t ccm_camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + ccm_camellia_setkey_wrap, + ccm_camellia_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +static const mbedtls_cipher_info_t camellia_128_ccm_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CCM, + MBEDTLS_MODE_CCM, + 128, + "CAMELLIA-128-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_ccm_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CCM, + MBEDTLS_MODE_CCM, + 192, + "CAMELLIA-192-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_ccm_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CCM, + MBEDTLS_MODE_CCM, + 256, + "CAMELLIA-256-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; +#endif /* MBEDTLS_CCM_C */ + +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) + +static int des_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + ((void) operation); + return mbedtls_des_crypt_ecb( (mbedtls_des_context *) ctx, input, output ); +} + +static int des3_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + ((void) operation); + return mbedtls_des3_crypt_ecb( (mbedtls_des3_context *) ctx, input, output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int des_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_des_crypt_cbc( (mbedtls_des_context *) ctx, operation, length, iv, input, + output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int des3_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_des3_crypt_cbc( (mbedtls_des3_context *) ctx, operation, length, iv, input, + output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static int des_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des_setkey_dec( (mbedtls_des_context *) ctx, key ); +} + +static int des_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des_setkey_enc( (mbedtls_des_context *) ctx, key ); +} + +static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set2key_dec( (mbedtls_des3_context *) ctx, key ); +} + +static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set2key_enc( (mbedtls_des3_context *) ctx, key ); +} + +static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set3key_dec( (mbedtls_des3_context *) ctx, key ); +} + +static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set3key_enc( (mbedtls_des3_context *) ctx, key ); +} + +static void * des_ctx_alloc( void ) +{ + mbedtls_des_context *des = mbedtls_calloc( 1, sizeof( mbedtls_des_context ) ); + + if( des == NULL ) + return( NULL ); + + mbedtls_des_init( des ); + + return( des ); +} + +static void des_ctx_free( void *ctx ) +{ + mbedtls_des_free( (mbedtls_des_context *) ctx ); + mbedtls_free( ctx ); +} + +static void * des3_ctx_alloc( void ) +{ + mbedtls_des3_context *des3; + des3 = mbedtls_calloc( 1, sizeof( mbedtls_des3_context ) ); + + if( des3 == NULL ) + return( NULL ); + + mbedtls_des3_init( des3 ); + + return( des3 ); +} + +static void des3_ctx_free( void *ctx ) +{ + mbedtls_des3_free( (mbedtls_des3_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t des_info = { + MBEDTLS_CIPHER_ID_DES, + des_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des_setkey_enc_wrap, + des_setkey_dec_wrap, + des_ctx_alloc, + des_ctx_free +}; + +static const mbedtls_cipher_info_t des_ecb_info = { + MBEDTLS_CIPHER_DES_ECB, + MBEDTLS_MODE_ECB, + MBEDTLS_KEY_LENGTH_DES, + "DES-ECB", + 8, + 0, + 8, + &des_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_cbc_info = { + MBEDTLS_CIPHER_DES_CBC, + MBEDTLS_MODE_CBC, + MBEDTLS_KEY_LENGTH_DES, + "DES-CBC", + 8, + 0, + 8, + &des_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static const mbedtls_cipher_base_t des_ede_info = { + MBEDTLS_CIPHER_ID_DES, + des3_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des3_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des3_set2key_enc_wrap, + des3_set2key_dec_wrap, + des3_ctx_alloc, + des3_ctx_free +}; + +static const mbedtls_cipher_info_t des_ede_ecb_info = { + MBEDTLS_CIPHER_DES_EDE_ECB, + MBEDTLS_MODE_ECB, + MBEDTLS_KEY_LENGTH_DES_EDE, + "DES-EDE-ECB", + 8, + 0, + 8, + &des_ede_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_ede_cbc_info = { + MBEDTLS_CIPHER_DES_EDE_CBC, + MBEDTLS_MODE_CBC, + MBEDTLS_KEY_LENGTH_DES_EDE, + "DES-EDE-CBC", + 8, + 0, + 8, + &des_ede_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static const mbedtls_cipher_base_t des_ede3_info = { + MBEDTLS_CIPHER_ID_3DES, + des3_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des3_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des3_set3key_enc_wrap, + des3_set3key_dec_wrap, + des3_ctx_alloc, + des3_ctx_free +}; + +static const mbedtls_cipher_info_t des_ede3_ecb_info = { + MBEDTLS_CIPHER_DES_EDE3_ECB, + MBEDTLS_MODE_ECB, + MBEDTLS_KEY_LENGTH_DES_EDE3, + "DES-EDE3-ECB", + 8, + 0, + 8, + &des_ede3_info +}; +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_ede3_cbc_info = { + MBEDTLS_CIPHER_DES_EDE3_CBC, + MBEDTLS_MODE_CBC, + MBEDTLS_KEY_LENGTH_DES_EDE3, + "DES-EDE3-CBC", + 8, + 0, + 8, + &des_ede3_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_BLOWFISH_C) + +static int blowfish_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_blowfish_crypt_ecb( (mbedtls_blowfish_context *) ctx, operation, input, + output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int blowfish_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, unsigned char *iv, const unsigned char *input, + unsigned char *output ) +{ + return mbedtls_blowfish_crypt_cbc( (mbedtls_blowfish_context *) ctx, operation, length, iv, + input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int blowfish_crypt_cfb64_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_blowfish_crypt_cfb64( (mbedtls_blowfish_context *) ctx, operation, length, + iv_off, iv, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_blowfish_crypt_ctr( (mbedtls_blowfish_context *) ctx, length, nc_off, + nonce_counter, stream_block, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static int blowfish_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_blowfish_setkey( (mbedtls_blowfish_context *) ctx, key, key_bitlen ); +} + +static void * blowfish_ctx_alloc( void ) +{ + mbedtls_blowfish_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_blowfish_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_blowfish_init( ctx ); + + return( ctx ); +} + +static void blowfish_ctx_free( void *ctx ) +{ + mbedtls_blowfish_free( (mbedtls_blowfish_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t blowfish_info = { + MBEDTLS_CIPHER_ID_BLOWFISH, + blowfish_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + blowfish_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + blowfish_crypt_cfb64_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + blowfish_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + blowfish_setkey_wrap, + blowfish_setkey_wrap, + blowfish_ctx_alloc, + blowfish_ctx_free +}; + +static const mbedtls_cipher_info_t blowfish_ecb_info = { + MBEDTLS_CIPHER_BLOWFISH_ECB, + MBEDTLS_MODE_ECB, + 128, + "BLOWFISH-ECB", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t blowfish_cbc_info = { + MBEDTLS_CIPHER_BLOWFISH_CBC, + MBEDTLS_MODE_CBC, + 128, + "BLOWFISH-CBC", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t blowfish_cfb64_info = { + MBEDTLS_CIPHER_BLOWFISH_CFB64, + MBEDTLS_MODE_CFB, + 128, + "BLOWFISH-CFB64", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t blowfish_ctr_info = { + MBEDTLS_CIPHER_BLOWFISH_CTR, + MBEDTLS_MODE_CTR, + 128, + "BLOWFISH-CTR", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ +#endif /* MBEDTLS_BLOWFISH_C */ + +#if defined(MBEDTLS_ARC4_C) +static int arc4_crypt_stream_wrap( void *ctx, size_t length, + const unsigned char *input, + unsigned char *output ) +{ + return( mbedtls_arc4_crypt( (mbedtls_arc4_context *) ctx, length, input, output ) ); +} + +static int arc4_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + /* we get key_bitlen in bits, arc4 expects it in bytes */ + if( key_bitlen % 8 != 0 ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + mbedtls_arc4_setup( (mbedtls_arc4_context *) ctx, key, key_bitlen / 8 ); + return( 0 ); +} + +static void * arc4_ctx_alloc( void ) +{ + mbedtls_arc4_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_arc4_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_arc4_init( ctx ); + + return( ctx ); +} + +static void arc4_ctx_free( void *ctx ) +{ + mbedtls_arc4_free( (mbedtls_arc4_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t arc4_base_info = { + MBEDTLS_CIPHER_ID_ARC4, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + arc4_crypt_stream_wrap, +#endif + arc4_setkey_wrap, + arc4_setkey_wrap, + arc4_ctx_alloc, + arc4_ctx_free +}; + +static const mbedtls_cipher_info_t arc4_128_info = { + MBEDTLS_CIPHER_ARC4_128, + MBEDTLS_MODE_STREAM, + 128, + "ARC4-128", + 0, + 0, + 1, + &arc4_base_info +}; +#endif /* MBEDTLS_ARC4_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +static int null_crypt_stream( void *ctx, size_t length, + const unsigned char *input, + unsigned char *output ) +{ + ((void) ctx); + memmove( output, input, length ); + return( 0 ); +} + +static int null_setkey( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) ctx); + ((void) key); + ((void) key_bitlen); + + return( 0 ); +} + +static void * null_ctx_alloc( void ) +{ + return( (void *) 1 ); +} + +static void null_ctx_free( void *ctx ) +{ + ((void) ctx); +} + +static const mbedtls_cipher_base_t null_base_info = { + MBEDTLS_CIPHER_ID_NULL, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + null_crypt_stream, +#endif + null_setkey, + null_setkey, + null_ctx_alloc, + null_ctx_free +}; + +static const mbedtls_cipher_info_t null_cipher_info = { + MBEDTLS_CIPHER_NULL, + MBEDTLS_MODE_STREAM, + 0, + "NULL", + 0, + 0, + 1, + &null_base_info +}; +#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */ + +const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = +{ +#if defined(MBEDTLS_AES_C) + { MBEDTLS_CIPHER_AES_128_ECB, &aes_128_ecb_info }, + { MBEDTLS_CIPHER_AES_192_ECB, &aes_192_ecb_info }, + { MBEDTLS_CIPHER_AES_256_ECB, &aes_256_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_AES_128_CBC, &aes_128_cbc_info }, + { MBEDTLS_CIPHER_AES_192_CBC, &aes_192_cbc_info }, + { MBEDTLS_CIPHER_AES_256_CBC, &aes_256_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_AES_128_CFB128, &aes_128_cfb128_info }, + { MBEDTLS_CIPHER_AES_192_CFB128, &aes_192_cfb128_info }, + { MBEDTLS_CIPHER_AES_256_CFB128, &aes_256_cfb128_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_AES_128_CTR, &aes_128_ctr_info }, + { MBEDTLS_CIPHER_AES_192_CTR, &aes_192_ctr_info }, + { MBEDTLS_CIPHER_AES_256_CTR, &aes_256_ctr_info }, +#endif +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info }, + { MBEDTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info }, + { MBEDTLS_CIPHER_AES_256_GCM, &aes_256_gcm_info }, +#endif +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_CIPHER_AES_128_CCM, &aes_128_ccm_info }, + { MBEDTLS_CIPHER_AES_192_CCM, &aes_192_ccm_info }, + { MBEDTLS_CIPHER_AES_256_CCM, &aes_256_ccm_info }, +#endif +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_ARC4_C) + { MBEDTLS_CIPHER_ARC4_128, &arc4_128_info }, +#endif + +#if defined(MBEDTLS_BLOWFISH_C) + { MBEDTLS_CIPHER_BLOWFISH_ECB, &blowfish_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_BLOWFISH_CBC, &blowfish_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_BLOWFISH_CFB64, &blowfish_cfb64_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_BLOWFISH_CTR, &blowfish_ctr_info }, +#endif +#endif /* MBEDTLS_BLOWFISH_C */ + +#if defined(MBEDTLS_CAMELLIA_C) + { MBEDTLS_CIPHER_CAMELLIA_128_ECB, &camellia_128_ecb_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_ECB, &camellia_192_ecb_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_ECB, &camellia_256_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_CAMELLIA_128_CBC, &camellia_128_cbc_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CBC, &camellia_192_cbc_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CBC, &camellia_256_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_CAMELLIA_128_CFB128, &camellia_128_cfb128_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CFB128, &camellia_192_cfb128_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CFB128, &camellia_256_cfb128_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_CAMELLIA_128_CTR, &camellia_128_ctr_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CTR, &camellia_192_ctr_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CTR, &camellia_256_ctr_info }, +#endif +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_CIPHER_CAMELLIA_128_GCM, &camellia_128_gcm_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_GCM, &camellia_192_gcm_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_GCM, &camellia_256_gcm_info }, +#endif +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_CIPHER_CAMELLIA_128_CCM, &camellia_128_ccm_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CCM, &camellia_192_ccm_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CCM, &camellia_256_ccm_info }, +#endif +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) + { MBEDTLS_CIPHER_DES_ECB, &des_ecb_info }, + { MBEDTLS_CIPHER_DES_EDE_ECB, &des_ede_ecb_info }, + { MBEDTLS_CIPHER_DES_EDE3_ECB, &des_ede3_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_DES_CBC, &des_cbc_info }, + { MBEDTLS_CIPHER_DES_EDE_CBC, &des_ede_cbc_info }, + { MBEDTLS_CIPHER_DES_EDE3_CBC, &des_ede3_cbc_info }, +#endif +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) + { MBEDTLS_CIPHER_NULL, &null_cipher_info }, +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ + + { MBEDTLS_CIPHER_NONE, NULL } +}; + +#define NUM_CIPHERS sizeof mbedtls_cipher_definitions / sizeof mbedtls_cipher_definitions[0] +int mbedtls_cipher_supported[NUM_CIPHERS]; + +#endif /* MBEDTLS_CIPHER_C */ diff --git a/libesp32/ESP32-Ethernet/README.md b/libesp32/ESP32-Ethernet/README.md new file mode 100644 index 000000000..ac4d80fa4 --- /dev/null +++ b/libesp32/ESP32-Ethernet/README.md @@ -0,0 +1,4 @@ +# Ethernet Arduino Library for ESP32 + +See https://github.com/espressif/arduino-esp32/issues/3554#issuecomment-596902806 + diff --git a/libesp32/ESP32-Ethernet/examples/EthernetLAN_IP101/EthernetLAN_IP101.ino b/libesp32/ESP32-Ethernet/examples/EthernetLAN_IP101/EthernetLAN_IP101.ino new file mode 100644 index 000000000..3bbe837a1 --- /dev/null +++ b/libesp32/ESP32-Ethernet/examples/EthernetLAN_IP101/EthernetLAN_IP101.ino @@ -0,0 +1,82 @@ +#include + +#define ETH_ADDR 1 +#define ETH_POWER_PIN 5 +#define ETH_MDC_PIN 23 +#define ETH_MDIO_PIN 18 +#define ETH_TYPE ETH_PHY_IP101 + +static bool eth_connected = false; + +void WiFiEvent(WiFiEvent_t event) +{ + switch (event) { + case SYSTEM_EVENT_ETH_START: + Serial.println("ETH Started"); + //set eth hostname here + ETH.setHostname("esp32-ethernet"); + break; + case SYSTEM_EVENT_ETH_CONNECTED: + Serial.println("ETH Connected"); + break; + case SYSTEM_EVENT_ETH_GOT_IP: + Serial.print("ETH MAC: "); + Serial.print(ETH.macAddress()); + Serial.print(", IPv4: "); + Serial.print(ETH.localIP()); + if (ETH.fullDuplex()) { + Serial.print(", FULL_DUPLEX"); + } + Serial.print(", "); + Serial.print(ETH.linkSpeed()); + Serial.println("Mbps"); + eth_connected = true; + break; + case SYSTEM_EVENT_ETH_DISCONNECTED: + Serial.println("ETH Disconnected"); + eth_connected = false; + break; + case SYSTEM_EVENT_ETH_STOP: + Serial.println("ETH Stopped"); + eth_connected = false; + break; + default: + break; + } +} + +void testClient(const char * host, uint16_t port) +{ + Serial.print("\nconnecting to "); + Serial.println(host); + + WiFiClient client; + if (!client.connect(host, port)) { + Serial.println("connection failed"); + return; + } + client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host); + while (client.connected() && !client.available()); + while (client.available()) { + Serial.write(client.read()); + } + + Serial.println("closing connection\n"); + client.stop(); +} + +void setup() +{ + Serial.begin(115200); + WiFi.onEvent(WiFiEvent); + ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE); +} + + +void loop() +{ + if (eth_connected) { + testClient("google.com", 80); + } + delay(10000); +} \ No newline at end of file diff --git a/libesp32/ESP32-Ethernet/library.properties b/libesp32/ESP32-Ethernet/library.properties new file mode 100644 index 000000000..50c7b8ea1 --- /dev/null +++ b/libesp32/ESP32-Ethernet/library.properties @@ -0,0 +1,17 @@ +name=ESP32 Ethernet + +version=1.1.0 + +author=Espressif + +maintainer=Espressif + +sentence=Ethernet Library for ESP32 + +paragraph=This library allows ESP32 to use ethernet hardware + +category=Communication + +url= + +architectures=esp32 diff --git a/libesp32/ESP32-Ethernet/src/ETH.cpp b/libesp32/ESP32-Ethernet/src/ETH.cpp new file mode 100644 index 000000000..2b3dd4390 --- /dev/null +++ b/libesp32/ESP32-Ethernet/src/ETH.cpp @@ -0,0 +1,299 @@ +/* + ETH.h - espre ETH PHY support. + Based on WiFi.h from Arduino WiFi shield library. + Copyright (c) 2011-2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "ETH.h" +#include "eth_phy/phy.h" +#include "eth_phy/phy_tlk110.h" +#include "eth_phy/phy_lan8720.h" +#include "eth_phy/phy_ip101.h" +#include "lwip/err.h" +#include "lwip/dns.h" + +extern void tcpipInit(); + +static int _eth_phy_mdc_pin = -1; +static int _eth_phy_mdio_pin = -1; +static int _eth_phy_power_pin = -1; +static eth_phy_power_enable_func _eth_phy_power_enable_orig = NULL; + +static void _eth_phy_config_gpio(void) +{ + if(_eth_phy_mdc_pin < 0 || _eth_phy_mdio_pin < 0){ + log_e("MDC and MDIO pins are not configured!"); + return; + } + phy_rmii_configure_data_interface_pins(); + phy_rmii_smi_configure_pins(_eth_phy_mdc_pin, _eth_phy_mdio_pin); +} + +static void _eth_phy_power_enable(bool enable) +{ + pinMode(_eth_phy_power_pin, OUTPUT); + digitalWrite(_eth_phy_power_pin, enable); + delay(1); +} + +ETHClass::ETHClass():initialized(false),started(false),staticIP(false) +{ +} + +ETHClass::~ETHClass() +{} + +bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t type, eth_clock_mode_t clock_mode) +{ + esp_err_t err; + if(initialized){ + err = esp_eth_enable(); + if(err){ + log_e("esp_eth_enable error: %d", err); + return false; + } + started = true; + return true; + } + _eth_phy_mdc_pin = mdc; + _eth_phy_mdio_pin = mdio; + _eth_phy_power_pin = power; + + if(type == ETH_PHY_LAN8720) + { + eth_config_t config = phy_lan8720_default_ethernet_config; + memcpy(ð_config, &config, sizeof(eth_config_t)); + } + else if(type == ETH_PHY_TLK110) + { + eth_config_t config = phy_tlk110_default_ethernet_config; + memcpy(ð_config, &config, sizeof(eth_config_t)); + } + else if(type == ETH_PHY_IP101) + { + eth_config_t config = phy_ip101_default_ethernet_config; + memcpy(ð_config, &config, sizeof(eth_config_t)); + } + else + { + log_e("Bad ETH_PHY type: %u", (uint8_t)type); + return false; + } + + eth_config.phy_addr = (eth_phy_base_t)phy_addr; + eth_config.clock_mode = clock_mode; + eth_config.gpio_config = _eth_phy_config_gpio; + eth_config.tcpip_input = tcpip_adapter_eth_input; + if(_eth_phy_power_pin >= 0){ + _eth_phy_power_enable_orig = eth_config.phy_power_enable; + eth_config.phy_power_enable = _eth_phy_power_enable; + } + + tcpipInit(); + err = esp_eth_init(ð_config); + if(!err){ + initialized = true; + err = esp_eth_enable(); + if(err){ + log_e("esp_eth_enable error: %d", err); + } else { + started = true; + return true; + } + } else { + log_e("esp_eth_init error: %d", err); + } + return false; +} + +bool ETHClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2) +{ + esp_err_t err = ESP_OK; + tcpip_adapter_ip_info_t info; + + if(local_ip != (uint32_t)0x00000000){ + info.ip.addr = static_cast(local_ip); + info.gw.addr = static_cast(gateway); + info.netmask.addr = static_cast(subnet); + } else { + info.ip.addr = 0; + info.gw.addr = 0; + info.netmask.addr = 0; + } + + err = tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_ETH); + if(err != ESP_OK && err != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED){ + log_e("DHCP could not be stopped! Error: %d", err); + return false; + } + + err = tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_ETH, &info); + if(err != ERR_OK){ + log_e("STA IP could not be configured! Error: %d", err); + return false; +} + if(info.ip.addr){ + staticIP = true; + } else { + err = tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_ETH); + if(err != ESP_OK && err != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED){ + log_w("DHCP could not be started! Error: %d", err); + return false; + } + staticIP = false; + } + + ip_addr_t d; + d.type = IPADDR_TYPE_V4; + + if(dns1 != (uint32_t)0x00000000) { + // Set DNS1-Server + d.u_addr.ip4.addr = static_cast(dns1); + dns_setserver(0, &d); + } + + if(dns2 != (uint32_t)0x00000000) { + // Set DNS2-Server + d.u_addr.ip4.addr = static_cast(dns2); + dns_setserver(1, &d); + } + + return true; +} + +IPAddress ETHClass::localIP() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return IPAddress(ip.ip.addr); +} + +IPAddress ETHClass::subnetMask() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return IPAddress(ip.netmask.addr); +} + +IPAddress ETHClass::gatewayIP() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return IPAddress(ip.gw.addr); +} + +IPAddress ETHClass::dnsIP(uint8_t dns_no) +{ + ip_addr_t dns_ip = dns_getserver(dns_no); + return IPAddress(dns_ip.u_addr.ip4.addr); +} + +IPAddress ETHClass::broadcastIP() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return WiFiGenericClass::calculateBroadcast(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); +} + +IPAddress ETHClass::networkID() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return WiFiGenericClass::calculateNetworkID(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); +} + +uint8_t ETHClass::subnetCIDR() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return (uint8_t)0; + } + return WiFiGenericClass::calculateSubnetCIDR(IPAddress(ip.netmask.addr)); +} + +const char * ETHClass::getHostname() +{ + const char * hostname; + if(tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_ETH, &hostname)){ + return NULL; + } + return hostname; +} + +bool ETHClass::setHostname(const char * hostname) +{ + return tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_ETH, hostname) == 0; +} + +bool ETHClass::fullDuplex() +{ + return eth_config.phy_get_duplex_mode(); +} + +bool ETHClass::linkUp() +{ + return eth_config.phy_check_link(); +} + +uint8_t ETHClass::linkSpeed() +{ + return eth_config.phy_get_speed_mode()?100:10; +} + +bool ETHClass::enableIpV6() +{ + return tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_ETH) == 0; +} + +IPv6Address ETHClass::localIPv6() +{ + static ip6_addr_t addr; + if(tcpip_adapter_get_ip6_linklocal(TCPIP_ADAPTER_IF_ETH, &addr)){ + return IPv6Address(); + } + return IPv6Address(addr.addr); +} + +uint8_t * macAddress(uint8_t* mac) +{ + if(!mac){ + return NULL; + } + esp_eth_get_mac(mac); + return mac; +} + +String ETHClass::macAddress(void) +{ + uint8_t mac[6]; + char macStr[18] = { 0 }; + esp_eth_get_mac(mac); + sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return String(macStr); +} + +ETHClass ETH; diff --git a/libesp32/ESP32-Ethernet/src/ETH.h b/libesp32/ESP32-Ethernet/src/ETH.h new file mode 100644 index 000000000..7f175e13f --- /dev/null +++ b/libesp32/ESP32-Ethernet/src/ETH.h @@ -0,0 +1,95 @@ +/* + ETH.h - espre ETH PHY support. + Based on WiFi.h from Ardiono WiFi shield library. + Copyright (c) 2011-2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _ETH_H_ +#define _ETH_H_ + +#include "WiFi.h" +#include "esp_eth.h" + +#ifndef ETH_PHY_ADDR +#define ETH_PHY_ADDR 0 +#endif + +#ifndef ETH_PHY_TYPE +#define ETH_PHY_TYPE ETH_PHY_LAN8720 +#endif + +#ifndef ETH_PHY_POWER +#define ETH_PHY_POWER -1 +#endif + +#ifndef ETH_PHY_MDC +#define ETH_PHY_MDC 23 +#endif + +#ifndef ETH_PHY_MDIO +#define ETH_PHY_MDIO 18 +#endif + +#ifndef ETH_CLK_MODE +#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN +#endif + +typedef enum { ETH_PHY_LAN8720, ETH_PHY_TLK110, ETH_PHY_IP101, ETH_PHY_MAX } eth_phy_type_t; + +class ETHClass { + private: + bool initialized; + bool started; + bool staticIP; + eth_config_t eth_config; + public: + ETHClass(); + ~ETHClass(); + + bool begin(uint8_t phy_addr=ETH_PHY_ADDR, int power=ETH_PHY_POWER, int mdc=ETH_PHY_MDC, int mdio=ETH_PHY_MDIO, eth_phy_type_t type=ETH_PHY_TYPE, eth_clock_mode_t clk_mode=ETH_CLK_MODE); + + bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000); + + const char * getHostname(); + bool setHostname(const char * hostname); + + bool fullDuplex(); + bool linkUp(); + uint8_t linkSpeed(); + + bool enableIpV6(); + IPv6Address localIPv6(); + + IPAddress localIP(); + IPAddress subnetMask(); + IPAddress gatewayIP(); + IPAddress dnsIP(uint8_t dns_no = 0); + + IPAddress broadcastIP(); + IPAddress networkID(); + uint8_t subnetCIDR(); + + uint8_t * macAddress(uint8_t* mac); + String macAddress(); + + friend class WiFiClient; + friend class WiFiServer; +}; + +extern ETHClass ETH; + +#endif /* _ETH_H_ */ diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 330a9f966..3ba3a1d38 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -1,8 +1,19 @@ ## Unreleased (development) +### 8.3.1.6 20200617 + +- Add command ``Module2`` to configure fallback module on fast reboot (#8464) +- Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff +- Add library to be used for decoding Teleinfo (French Metering Smart Meter) +- Add support for single wire LMT01 temperature Sensor by justifiably (#8713) +- Change ESP32 USER GPIO template representation decreasing template message size +- Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT +- Change commands ``SlaveSend`` and ``SlaveReset`` into ``ClientSend`` and ``ClientReset`` + ### 8.3.1.5 20200616 - Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3`` +- Add Zigbee initial support for EmberZNet protocol (raw send/receive only) ### 8.3.1.4 20200615 diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 543a4c9b9..ccbb6b399 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -505,10 +505,14 @@ #define D_CMND_ZIGBEE_RESET "Reset" #define D_JSON_ZIGBEE_CC2530 "CC2530" #define D_CMND_ZIGBEEZNPRECEIVE "ZNPReceive" // only for debug +#define D_CMND_ZIGBEE_EZSP_RECEIVE "EZSPReceive" // only for debug #define D_CMND_ZIGBEEZNPSEND "ZNPSend" +#define D_CMND_ZIGBEE_EZSP_SEND "EZSPSend" #define D_JSON_ZIGBEE_STATE "ZbState" #define D_JSON_ZIGBEEZNPRECEIVED "ZbZNPReceived" + #define D_JSON_ZIGBEE_EZSP_RECEIVED "ZbEZSPReceived" #define D_JSON_ZIGBEEZNPSENT "ZbZNPSent" + #define D_JSON_ZIGBEE_EZSP_SENT "ZbEZSPSent" #define D_JSON_ZIGBEEZCL_RECEIVED "ZbZCLReceived" #define D_JSON_ZIGBEEZCL_RAW_RECEIVED "ZbZCLRawReceived" #define D_JSON_ZIGBEE_DEVICE "Device" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 73fab1f70..165e4f82a 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Подобрена комуникация" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Използвана енергия днес" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 9eed4e08f..7b53e6274 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Spotřeba Dnes" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index b24d9679a..4804ea7ba 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Erweiterte Kommunikation" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energie heute" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 1533346fe..3efac89e8 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Βελτίωση επικοινωνίας" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Ενέργεια σήμερα" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 3011c2aa1..1dd0429d8 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energy Today" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 430099098..e0141cf83 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Mejora de Comunicación" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX ESCENA TX" +#define D_KNX_RX_SCENE "KNX ESCENA RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energía Hoy" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index d4dbbb695..28e9e28b9 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Amélioration de la communication" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX Scène TX" +#define D_KNX_RX_SCENE "KNX Scène RX" // xsns_03_energy.ino #define D_ENERGY_TODAY "Énergie aujourd'hui" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "Hibernation" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Esclave TX" -#define D_SENSOR_SLAVE_RX "Esclave RX" -#define D_SENSOR_SLAVE_RESET "Esclave Rst" +#define D_SENSOR_CLIENT_TX "Esclave TX" +#define D_SENSOR_CLIENT_RX "Esclave RX" +#define D_SENSOR_CLIENT_RESET "Esclave Rst" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index cb3a83d7c..7cbc64acf 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "שיפור התקשורת" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "צריכה יומית" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index d7aa3b36b..07dfe6349 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Mai energia" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index c82ca66f4..ebd7addfe 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Miglioramento comunicazione" #define D_KNX_TX_SLOT "KNX - TX" #define D_KNX_RX_SLOT "KNX - RX" +#define D_KNX_TX_SCENE "Scena - TX" +#define D_KNX_RX_SCENE "Scena - RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energia - oggi" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 - DATI" #define D_SENSOR_DEEPSLEEP "Deep sleep" #define D_SENSOR_EXS_ENABLE "EXS - Abilita" -#define D_SENSOR_SLAVE_TX "Slave - TX" -#define D_SENSOR_SLAVE_RX "Slave - RX" -#define D_SENSOR_SLAVE_RESET "Slave - RST" +#define D_SENSOR_CLIENT_TX "Client - TX" +#define D_SENSOR_CLIENT_RX "Client - RX" +#define D_SENSOR_CLIENT_RESET "Client - RST" #define D_SENSOR_GPS_RX "GPS - RX" #define D_SENSOR_GPS_TX "GPS - TX" #define D_SENSOR_HM10_RX "HM10 - RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "Velocità vento" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 55137c085..0a4cb7633 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "커뮤니케이션 강화" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "금일 전력 사용량" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index faf3a35da..819b39045 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Verbeter verbinding" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Verbruik vandaag" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 28be27c64..2cb92290e 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Rozszerzenia" #define D_KNX_TX_SLOT "Gniazdo TX" #define D_KNX_RX_SLOT "Gniazdo RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energia dzisiaj" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "Głęboko uśpiony" #define D_SENSOR_EXS_ENABLE "Załącz EXS" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 9ee7e4066..5e866f809 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Melhoria da comunicação" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Consumo energético de hoje" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 424e7dd80..af5e2f7aa 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Melhoria de Comunicação" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Consumo energético de hoje" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index a45798e13..3e8418960 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Îmbunătățire Communicație" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energia de Azi" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 26e9064f1..af5ef942d 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Энергия Сегодня" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 211f070dd..06251277c 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Spotreba dnes" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index ffb393796..74c30ef32 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Kommuniceringsförbättring" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energi idag" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index f11bddaa0..97a03b15b 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energy Today" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index d6dea2da6..07a60ee5b 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Підвищення зв'язку" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Енергія Сьогодні" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index e83253105..92dc25766 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "通讯增强" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "今日用电量" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index fbf7e3e4c..91339b304 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -445,6 +445,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "今日用電量" @@ -663,9 +665,9 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" @@ -681,6 +683,7 @@ #define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" #define D_GPIO_WEBCAM_RESET "CAM_RESET" #define D_GPIO_WEBCAM_XCLK "CAM_XCLK" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 1e8d59881..4f5623de1 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -50,7 +50,12 @@ #define PROJECT "tasmota" // PROJECT is used as the default topic delimiter // If not selected the default will be SONOFF_BASIC -//#define MODULE SONOFF_BASIC // [Module] Select default model from tasmota_template.h +//#define MODULE SONOFF_BASIC // [Module] Select default module from tasmota_template.h +#ifdef ESP8266 +#define FALLBACK_MODULE SONOFF_BASIC // [Module2] Select default module on fast reboot where USER_MODULE is user template +#else // ESP32 +#define FALLBACK_MODULE WEMOS // [Module2] Select default module on fast reboot where USER_MODULE is user template +#endif #define SAVE_DATA 1 // [SaveData] Save changed parameters to Flash (0 = disable, 1 - 3600 seconds) #define SAVE_STATE true // [SetOption0] Save changed power state to Flash (false = disable, true = enable) @@ -135,6 +140,8 @@ // -- MQTT - Home Assistant Discovery ------------- #define HOME_ASSISTANT_DISCOVERY_ENABLE false // [SetOption19] Home Assistant Discovery (false = Disable, true = Enable) #define HASS_AS_LIGHT false // [SetOption30] Enforce HAss autodiscovery as light +//#define DEEPSLEEP_LWT_HA_DISCOVERY // Enable LWT topic and its payloads for read-only sensors (Status sensor not included) and binary_sensors on HAss Discovery (Commented out: all read-only sensors and binary_sensors + // won't be shown as OFFLINE on Home Assistant when the device is DeepSleeping - NOTE: This is only for read-only sensors and binary_sensors, relays will be shown as OFFLINE) // -- MQTT - Options ------------------------------ #define MQTT_RESULT_COMMAND false // [SetOption4] Switch between MQTT RESULT or COMMAND @@ -591,12 +598,10 @@ // #define USE_FLOG // Add support for GPS logging in OTA's Flash (Experimental) (+2k9 code, +8 bytes RAM) //#define USE_HM10 // (ESP8266 only) Add support for HM-10 as a BLE-bridge (+9k3 code) //#define USE_HRXL // Add support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) -//#define USE_TASMOTA_SLAVE // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k6 code, 64 mem) - #define USE_TASMOTA_SLAVE_FLASH_SPEED 57600 // Usually 57600 for 3.3V variants and 115200 for 5V variants - #define USE_TASMOTA_SLAVE_SERIAL_SPEED 57600 // Depends on the sketch that is running on the Uno/Pro Mini +//#define USE_TASMOTA_CLIENT // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k6 code, 64 mem) + #define USE_TASMOTA_CLIENT_FLASH_SPEED 57600 // Usually 57600 for 3.3V variants and 115200 for 5V variants + #define USE_TASMOTA_CLIENT_SERIAL_SPEED 57600 // Depends on the sketch that is running on the Uno/Pro Mini //#define USE_OPENTHERM // Add support for OpenTherm (+15k code) -#define USE_TELEINFO // Add support for Teleinfo via serial RX interface - //#define USE_TELEINFO_STANDARD // Use standard mode (9600 bps) else it's historical mode (1200 bps) // -- Power monitoring sensors -------------------- #define USE_ENERGY_MARGIN_DETECTION // Add support for Energy Margin detection (+1k6 code) @@ -620,6 +625,8 @@ #define LE01MR_SPEED 9600 // LE-01MR modbus baudrate (default: 9600) #define LE01MR_ADDR 1 // LE-01MR modbus address (default: 0x01) #define USE_BL0940 // Add support for BL0940 Energy monitor as used in Blitzwolf SHP-10 (+1k6 code) +//#define USE_TELEINFO // Add support for Teleinfo via serial RX interface (+5k2 code, +168 RAM + SmartMeter LinkedList Values RAM) +// #define USE_TELEINFO_STANDARD // Use standard mode (9600 bps) else it's historical mode (1200 bps) // -- Low level interface devices ----------------- #define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor (1k6 code) @@ -630,6 +637,7 @@ #define MAX31865_PTD_RES 100 // Nominal PTD resistance at 0°C (100Ω for a PT100, 1000Ω for a PT1000, YMMV!) #define MAX31865_REF_RES 430 // Reference resistor (Usually 430Ω for a PT100, 4300Ω for a PT1000) #define MAX31865_PTD_BIAS 0 // To calibrate your not-so-good PTD +//#define USE_LMT01 // Add support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code) // -- IR Remote features - all protocols from IRremoteESP8266 -------------------------- // IR Full Protocols mode is activated through platform.io only. @@ -654,6 +662,9 @@ // -- Zigbee interface ---------------------------- //#define USE_ZIGBEE // Enable serial communication with Zigbee CC2530 flashed with ZNP (+49k code, +3k mem) + #define USE_ZIGBEE_ZNP // Enable ZNP protocol, needed for CC2530 based devices + // #define USE_ZIGBEE_EZSP // [EXPERIMENTAL - DO NOT USE] Enable EZSP protocol, needed for EFR32 EmberZNet based devices, like Sonoff Zigbee bridge + // Note: USE_ZIGBEE_ZNP and USE_ZIGBEE_EZSP are mutually incompatible, you must select exactly one #define USE_ZIGBEE_PANID 0x1A63 // arbitrary PAN ID for Zigbee network, must be unique in the home // if PANID == 0xFFFF, then the device will act as a Zigbee router, the parameters below are ignored // if PANID == 0xFFFE, then the device will act as a Zigbee end-device (non-router), the parameters below are ignored @@ -732,9 +743,13 @@ //#define USE_ETHERNET // Add support for ethernet (Currently fixed for Olimex ESP32-PoE) // Olimex ESP32-PoE - #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110 + #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110, 2 = ETH_PHY_IP101 #define ETH_ADDR 0 // [EthAddress] 0 = PHY0 .. 31 = PHY31 #define ETH_CLKMODE 3 // [EthClockMode] 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT + // wESP32-PoE +// #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110, 2 = ETH_PHY_IP101 +// #define ETH_ADDR 0 // [EthAddress] 0 = PHY0 .. 31 = PHY31 +// #define ETH_CLKMODE 0 // [EthClockMode] 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT //#define USE_SPI // Add support for hardware SPI //#define USE_MI_ESP32 // Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) diff --git a/tasmota/settings.h b/tasmota/settings.h index 80507e97b..0704f426f 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -567,11 +567,12 @@ struct { uint16_t windmeter_pulse_debounce; // F3A int16_t windmeter_speed_factor; // F3C uint8_t windmeter_tele_pchange; // F3E - uint8_t ledpwm_on; // F3F - uint8_t ledpwm_off; // F40 + uint8_t ledpwm_on; // F3F + uint8_t ledpwm_off; // F40 uint8_t tcp_baudrate; // F41 + uint8_t fallback_module; // F42 - uint8_t free_f42[118]; // F42 - Decrement if adding new Setting variables just above and below + uint8_t free_f43[117]; // F43 - Decrement if adding new Setting variables just above and below // Only 32 bit boundary variables below uint16_t pulse_counter_debounce_low; // FB8 diff --git a/tasmota/settings.ino b/tasmota/settings.ino index a294e2813..d7ede5f25 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -768,6 +768,7 @@ void SettingsDefaultSet2(void) // flag.interlock |= 0; Settings.interlock[0] = 0xFF; // Legacy support using all relays in one interlock group Settings.module = MODULE; + Settings.fallback_module = FALLBACK_MODULE; ModuleDefault(WEMOS); // for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { Settings.my_gp.io[i] = GPIO_NONE; } SettingsUpdateText(SET_FRIENDLYNAME1, PSTR(FRIENDLY_NAME)); @@ -1452,12 +1453,15 @@ void SettingsDelta(void) Settings.flag4.network_wifi = 1; Settings.flag4.network_ethernet = 1; } - if (Settings.version < 0x08030105) { #ifdef ESP32 + if (Settings.version < 0x08030105) { Settings.eth_type = ETH_TYPE; Settings.eth_clk_mode = ETH_CLKMODE; Settings.eth_address = ETH_ADDR; + } #endif + if (Settings.version < 0x08030106) { + Settings.fallback_module = FALLBACK_MODULE; } Settings.version = VERSION; diff --git a/tasmota/support.ino b/tasmota/support.ino index 8b2c144f7..87cd0ce5e 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1359,7 +1359,15 @@ bool JsonTemplate(const char* dataBuf) } if (obj[D_JSON_GPIO].success()) { for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) { +#ifdef ESP8266 Settings.user_template.gp.io[i] = obj[D_JSON_GPIO][i] | 0; +#else // ESP32 + uint16_t gpio = obj[D_JSON_GPIO][i] | 0; + if (gpio == (AGPIO(GPIO_NONE) +1)) { + gpio = AGPIO(GPIO_USER); + } + Settings.user_template.gp.io[i] = gpio; +#endif } } if (obj[D_JSON_FLAG].success()) { @@ -1378,7 +1386,15 @@ void TemplateJson(void) { Response_P(PSTR("{\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), SettingsText(SET_TEMPLATE_NAME)); for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) { +#ifdef ESP8266 ResponseAppend_P(PSTR("%s%d"), (i>0)?",":"", Settings.user_template.gp.io[i]); +#else // ESP32 + uint16_t gpio = Settings.user_template.gp.io[i]; + if (gpio == AGPIO(GPIO_USER)) { + gpio = AGPIO(GPIO_NONE) +1; + } + ResponseAppend_P(PSTR("%s%d"), (i>0)?",":"", gpio); +#endif } ResponseAppend_P(PSTR("],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"), Settings.user_template.flag, Settings.user_template_base +1); } @@ -1604,8 +1620,8 @@ void I2cScan(char *devs, unsigned int devs_len) // Return error codes defined in twi.h and core_esp8266_si2c.c // I2C_OK 0 // I2C_SCL_HELD_LOW 1 = SCL held low by another device, no procedure available to recover - // I2C_SCL_HELD_LOW_AFTER_READ 2 = I2C bus error. SCL held low beyond slave clock stretch time - // I2C_SDA_HELD_LOW 3 = I2C bus error. SDA line held low by slave/another_master after n bits + // I2C_SCL_HELD_LOW_AFTER_READ 2 = I2C bus error. SCL held low beyond client clock stretch time + // I2C_SDA_HELD_LOW 3 = I2C bus error. SDA line held low by client/another_master after n bits // I2C_SDA_HELD_LOW_AFTER_INIT 4 = line busy. SDA again held low by another device. 2nd master? uint8_t error = 0; diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 5d0180005..a901b380d 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1018,18 +1018,29 @@ void CmndModule(void) present = ValidTemplateModule(XdrvMailbox.payload); } if (present) { - Settings.last_module = Settings.module; - Settings.module = XdrvMailbox.payload; - SetModuleType(); - if (Settings.last_module != XdrvMailbox.payload) { - for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { - Settings.my_gp.io[i] = GPIO_NONE; + if (XdrvMailbox.index == 2) { + Settings.fallback_module = XdrvMailbox.payload; + } else { + Settings.last_module = Settings.module; + Settings.module = XdrvMailbox.payload; + SetModuleType(); + if (Settings.last_module != XdrvMailbox.payload) { + for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { + Settings.my_gp.io[i] = GPIO_NONE; + } } + restart_flag = 2; } - restart_flag = 2; } } - Response_P(S_JSON_COMMAND_NVALUE_SVALUE, XdrvMailbox.command, ModuleNr(), ModuleName().c_str()); + uint8_t module_real = Settings.module; + uint8_t module_number = ModuleNr(); + if (XdrvMailbox.index == 2) { + module_real = Settings.fallback_module; + module_number = (USER_MODULE == Settings.fallback_module) ? 0 : Settings.fallback_module +1; + strcat(XdrvMailbox.command, "2"); + } + Response_P(S_JSON_COMMAND_NVALUE_SVALUE, XdrvMailbox.command, module_number, AnyModuleName(module_real).c_str()); } void CmndModules(void) diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 5e582b0f9..abd5f4236 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -477,8 +477,8 @@ void GetFeatures(void) #ifdef USE_EXS_DIMMER feature5 |= 0x00008000; // xdrv_30_exs_dimmer.ino #endif -#ifdef USE_TASMOTA_SLAVE - feature5 |= 0x00010000; // xdrv_31_arduino_slave.ino +#ifdef USE_TASMOTA_CLIENT + feature5 |= 0x00010000; // xdrv_31_tasmota_client.ino #endif #ifdef USE_HIH6 feature5 |= 0x00020000; // xsns_55_hih_series.ino @@ -587,8 +587,9 @@ void GetFeatures(void) #ifdef USE_TELEINFO feature6 |= 0x00040000; // xnrg_15_teleinfo.ino #endif - -// feature6 |= 0x00080000; +#ifdef USE_LMT01 + feature6 |= 0x00080000; // xsns_74_lmt01.ino +#endif // feature6 |= 0x00100000; // feature6 |= 0x00200000; diff --git a/tasmota/support_rtc.ino b/tasmota/support_rtc.ino index 445976eb3..25ad82435 100644 --- a/tasmota/support_rtc.ino +++ b/tasmota/support_rtc.ino @@ -379,7 +379,7 @@ void RtcSecond(void) Rtc.millis = millis(); if (!Rtc.user_time_entry) { - if (!global_state.wifi_down) { + if (!global_state.network_down) { uint8_t uptime_minute = (uptime / 60) % 60; // 0 .. 59 if ((Rtc.ntp_sync_minute > 59) && (uptime_minute > 2)) { Rtc.ntp_sync_minute = 1; // If sync prepare for a new cycle diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index 3d3811c89..4eceddb5c 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -203,7 +203,8 @@ const uint32_t LOOP_SLEEP_DELAY = 50; // Lowest number of milliseconds to #define KNX_SLOT3 28 #define KNX_SLOT4 29 #define KNX_SLOT5 30 -#define KNX_MAX_device_param 30 +#define KNX_SCENE 31 +#define KNX_MAX_device_param 31 #define MAX_KNXTX_CMNDS 5 /*********************************************************************************************\ diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 2c93f1b88..abc95d5d9 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -278,12 +278,8 @@ void setup(void) { #endif } if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +4) { // Restarted 6 times -#ifdef ESP8266 - Settings.module = SONOFF_BASIC; // Reset module to Sonoff Basic - // Settings.last_module = SONOFF_BASIC; -#else // ESP32 - Settings.module = WEMOS; // Reset module to Wemos -#endif // ESP8266 - ESP32 + Settings.module = Settings.fallback_module; // Reset module to fallback module +// Settings.last_module = Settings.fallback_module; } AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_LOG_SOME_SETTINGS_RESET " (%d)"), RtcReboot.fast_reboot_count); } diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index eb58d30e5..10f183ec5 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -152,7 +152,7 @@ #define USE_HM10 // (ESP8266 only) Add support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) //#define USE_MI_ESP32 // (ESP32 only) Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #define USE_HRXL // Add support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) -//#define USE_TASMOTA_SLAVE // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +//#define USE_TASMOTA_CLIENT // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) //#define USE_OPENTHERM // Add support for OpenTherm (+15k code) //#define USE_MCP9808 // Add support for MCP9808 temperature sensor (+0k9 code) //#define USE_HP303B // Add support for HP303B temperature and pressure sensor (I2C address 0x76 or 0x77) (+6k2 code) @@ -176,6 +176,7 @@ #define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram) #define USE_IR_RECEIVE // Support for IR receiver (+5k5 code, 264 iram) +#define USE_LMT01 // Add support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code) #define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code) #define USE_TM1638 // Add support for TM1638 switches copying Switch1 .. Switch8 (+1k code) #define USE_HX711 // Add support for HX711 load cell (+1k5 code) @@ -382,7 +383,7 @@ #undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) -#undef USE_TASMOTA_SLAVE // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) //#define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor @@ -487,7 +488,7 @@ #undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) -#undef USE_TASMOTA_SLAVE // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) //#undef USE_ENERGY_SENSOR // Disable energy sensors @@ -614,7 +615,7 @@ #undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) #undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) -#undef USE_TASMOTA_SLAVE // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) #undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) #undef USE_ENERGY_SENSOR // Disable energy sensors diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index c2acc6911..620c6ff68 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -69,6 +69,18 @@ String EthernetMacAddress(void); #ifdef USE_EMULATION_WEMO #define USE_EMULATION #endif + +// Convert legacy slave to client +#ifdef USE_TASMOTA_SLAVE +#define USE_TASMOTA_CLIENT +#endif +#ifdef USE_TASMOTA_SLAVE_FLASH_SPEED +#define USE_TASMOTA_CLIENT_FLASH_SPEED USE_TASMOTA_SLAVE_FLASH_SPEED +#endif +#ifdef USE_TASMOTA_SLAVE_SERIAL_SPEED +#define USE_TASMOTA_CLIENT_SERIAL_SPEED USE_TASMOTA_SLAVE_SERIAL_SPEED +#endif + // See https://github.com/esp8266/Arduino/pull/4889 #undef NO_EXTRA_4K_HEAP // Allocate 4k heap for WPS in ESP8166/Arduino core v2.4.2 (was always allocated in previous versions) @@ -287,6 +299,9 @@ const char kWebColors[] PROGMEM = #ifndef MODULE #define MODULE SONOFF_BASIC // [Module] Select default model #endif +#ifndef FALLBACK_MODULE +#define FALLBACK_MODULE SONOFF_BASIC // [Module2] Select default module on fast reboot where USER_MODULE is user template +#endif #ifndef ARDUINO_ESP8266_RELEASE #define ARDUINO_CORE_RELEASE "STAGE" @@ -301,6 +316,9 @@ const char kWebColors[] PROGMEM = #ifndef MODULE #define MODULE WEMOS // [Module] Select default model #endif +#ifndef FALLBACK_MODULE +#define FALLBACK_MODULE WEMOS // [Module2] Select default module on fast reboot where USER_MODULE is user template +#endif #ifndef ARDUINO_ESP32_RELEASE #define ARDUINO_CORE_RELEASE "STAGE" diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 6be969043..bd1c009de 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -137,8 +137,8 @@ enum UserSelectablePins { GPIO_TUYA_RX, // Tuya Serial interface GPIO_MGC3130_XFER, // MGC3130 Transfer GPIO_MGC3130_RESET, // MGC3130 Reset - GPIO_SSPI_MISO, // Software SPI Master Input Slave Output - GPIO_SSPI_MOSI, // Software SPI Master Output Slave Input + GPIO_SSPI_MISO, // Software SPI Master Input Client Output + GPIO_SSPI_MOSI, // Software SPI Master Output Client Input GPIO_SSPI_SCLK, // Software SPI Serial Clock GPIO_SSPI_CS, // Software SPI Chip Select GPIO_SSPI_DC, // Software SPI Data or Command @@ -210,10 +210,10 @@ enum UserSelectablePins { GPIO_SM2135_DAT, // SM2135 Dat GPIO_DEEPSLEEP, // Kill switch for deepsleep GPIO_EXS_ENABLE, // EXS MCU Enable - GPIO_TASMOTASLAVE_TXD, // Slave TX - GPIO_TASMOTASLAVE_RXD, // Slave RX - GPIO_TASMOTASLAVE_RST, // Slave Reset Pin - GPIO_TASMOTASLAVE_RST_INV, // Slave Reset Inverted + GPIO_TASMOTACLIENT_TXD, // Client TX + GPIO_TASMOTACLIENT_RXD, // Client RX + GPIO_TASMOTACLIENT_RST, // Client Reset Pin + GPIO_TASMOTACLIENT_RST_INV, // Client Reset Inverted GPIO_HPMA_RX, // Honeywell HPMA115S0 Serial interface GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface GPIO_GPS_RX, // GPS serial interface @@ -238,6 +238,7 @@ enum UserSelectablePins { GPIO_TCP_RX, // TCP Serial bridge GPIO_TELEINFO_RX, // TELEINFO serial interface GPIO_TELEINFO_ENABLE,// TELEINFO Enable PIN + GPIO_LMT01, // LMT01 input counting pin GPIO_SENSOR_END }; // Programmer selectable GPIO functionality @@ -316,7 +317,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_DDSU666_TX "|" D_SENSOR_DDSU666_RX "|" D_SENSOR_SM2135_CLK "|" D_SENSOR_SM2135_DAT "|" D_SENSOR_DEEPSLEEP "|" D_SENSOR_EXS_ENABLE "|" - D_SENSOR_SLAVE_TX "|" D_SENSOR_SLAVE_RX "|" D_SENSOR_SLAVE_RESET "|" D_SENSOR_SLAVE_RESET "i|" + D_SENSOR_CLIENT_TX "|" D_SENSOR_CLIENT_RX "|" D_SENSOR_CLIENT_RESET "|" D_SENSOR_CLIENT_RESET "i|" D_SENSOR_HPMA_RX "|" D_SENSOR_HPMA_TX "|" D_SENSOR_GPS_RX "|" D_SENSOR_GPS_TX "|" D_SENSOR_DS18X20 "o|" D_SENSOR_DHT11 "o|" @@ -328,9 +329,10 @@ const char kSensorNames[] PROGMEM = D_SENSOR_AS3935 "|" D_SENSOR_PMS5003_TX "|" D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|" D_SENSOR_WINDMETER_SPEED "|" - D_SENSOR_BL0940_RX "|" + D_SENSOR_BL0940_RX "|" D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|" - D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE + D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE "|" + D_SENSOR_LMT01_PULSE ; const char kSensorNamesFixed[] PROGMEM = @@ -430,8 +432,8 @@ const uint8_t kGpioNiceList[] PROGMEM = { #ifdef USE_SPI GPIO_SPI_CS, // SPI Chip Select GPIO_SPI_DC, // SPI Data Direction - GPIO_SSPI_MISO, // Software SPI Master Input Slave Output - GPIO_SSPI_MOSI, // Software SPI Master Output Slave Input + GPIO_SSPI_MISO, // Software SPI Master Input Client Output + GPIO_SSPI_MOSI, // Software SPI Master Output Client Input GPIO_SSPI_SCLK, // Software SPI Serial Clock GPIO_SSPI_CS, // Software SPI Chip Select GPIO_SSPI_DC, // Software SPI Data or Command @@ -450,6 +452,9 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_DSB, // Single wire DS18B20 or DS18S20 GPIO_DSB_OUT, // Pseudo Single wire DS18B20 or DS18S20 #endif +#ifdef USE_LMT01 // LMT01, count pulses on GPIO + GPIO_LMT01, +#endif // Light #ifdef USE_LIGHT @@ -625,11 +630,11 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_PN532_TXD, // PN532 HSU Tx GPIO_PN532_RXD, // PN532 HSU Rx #endif -#ifdef USE_TASMOTA_SLAVE - GPIO_TASMOTASLAVE_TXD, // Tasmota Slave TX - GPIO_TASMOTASLAVE_RXD, // Tasmota Slave RX - GPIO_TASMOTASLAVE_RST, // Tasmota Slave Reset - GPIO_TASMOTASLAVE_RST_INV, // Tasmota Slave Reset Inverted +#ifdef USE_TASMOTA_CLIENT + GPIO_TASMOTACLIENT_TXD, // Tasmota Client TX + GPIO_TASMOTACLIENT_RXD, // Tasmota Client RX + GPIO_TASMOTACLIENT_RST, // Tasmota Client Reset + GPIO_TASMOTACLIENT_RST_INV, // Tasmota Client Reset Inverted #endif #ifdef USE_RDM6300 GPIO_RDM6300_RX, @@ -783,7 +788,7 @@ enum SupportedModules { SUPLA1, WITTY, YUNSHAN, MAGICHOME, LUANIHVIO, KMC_70011, ARILUX_LC01, ARILUX_LC11, SONOFF_DUAL_R2, ARILUX_LC06, SONOFF_S31, ZENGGE_ZF_WF017, SONOFF_POW_R2, SONOFF_IFAN02, BLITZWOLF_BWSHP, SHELLY1, SHELLY2, PHILIPS, NEO_COOLCAM, ESP_SWITCH, OBI, TECKIN, APLIC_WDP303075, TUYA_DIMMER, GOSUND, ARMTRONIX_DIMMERS, SK03_TUYA, PS_16_DZ, TECKIN_US, MANZOKU_EU_4, - OBI2, YTF_IR_BRIDGE, DIGOO, KA10, ZX2820, MI_DESK_LAMP, SP10, WAGA, SYF05, SONOFF_L1, + OBI2, YTF_IR_BRIDGE, DIGOO, KA10, ZX2820, MI_DESK_LAMP, SP10, WAGA, SYF05, SONOFF_L1, SONOFF_IFAN03, EXS_DIMMER, PWM_DIMMER, SONOFF_D1, MAXMODULE}; @@ -2264,10 +2269,8 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_LED1_INV, // GPIO13 WiFi Blue Led - Link and Power status 0, 0, 0, 0 } - }; - #endif // ESP8266 #ifdef ESP32 diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index 6571dec1c..80a015675 100644 --- a/tasmota/tasmota_template_ESP32.h +++ b/tasmota/tasmota_template_ESP32.h @@ -102,8 +102,8 @@ enum UserSelectablePins { GPIO_SM2135_CLK, GPIO_SM2135_DAT, // SM2135 PWM controller GPIO_DEEPSLEEP, // Kill switch for deepsleep GPIO_EXS_ENABLE, // EXS MCU Enable - GPIO_TASMOTASLAVE_TXD, GPIO_TASMOTASLAVE_RXD, // Slave Serial interface - GPIO_TASMOTASLAVE_RST, GPIO_TASMOTASLAVE_RST_INV, // Slave Reset + GPIO_TASMOTACLIENT_TXD, GPIO_TASMOTACLIENT_RXD, // Client Serial interface + GPIO_TASMOTACLIENT_RST, GPIO_TASMOTACLIENT_RST_INV, // Client Reset GPIO_HPMA_RX, GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface GPIO_GPS_RX, GPIO_GPS_TX, // GPS Serial interface GPIO_HM10_RX, GPIO_HM10_TX, // HM10-BLE-Mijia-bridge Serial interface @@ -133,6 +133,7 @@ enum UserSelectablePins { GPIO_ETH_PHY_POWER, GPIO_ETH_PHY_MDC, GPIO_ETH_PHY_MDIO, // Ethernet GPIO_TELEINFO_RX, // Teleinfo telemetry data receive pin GPIO_TELEINFO_ENABLE, // Teleinfo Enable Receive Pin + GPIO_LMT01, // LMT01 input counting pin GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -199,7 +200,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_DDSU666_TX "|" D_SENSOR_DDSU666_RX "|" D_SENSOR_SM2135_CLK "|" D_SENSOR_SM2135_DAT "|" D_SENSOR_DEEPSLEEP "|" D_SENSOR_EXS_ENABLE "|" - D_SENSOR_SLAVE_TX "|" D_SENSOR_SLAVE_RX "|" D_SENSOR_SLAVE_RESET "|" D_SENSOR_SLAVE_RESET "_i|" + D_SENSOR_CLIENT_TX "|" D_SENSOR_CLIENT_RX "|" D_SENSOR_CLIENT_RESET "|" D_SENSOR_CLIENT_RESET "_i|" D_SENSOR_HPMA_RX "|" D_SENSOR_HPMA_TX "|" D_SENSOR_GPS_RX "|" D_SENSOR_GPS_TX "|" D_SENSOR_HM10_RX "|" D_SENSOR_HM10_TX "|" @@ -225,7 +226,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_BL0940_RX "|" D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|" D_SENSOR_ETH_PHY_POWER "|" D_SENSOR_ETH_PHY_MDC "|" D_SENSOR_ETH_PHY_MDIO "|" - D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE + D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE "|" + D_SENSOR_LMT01_PULSE ; const char kSensorNamesFixed[] PROGMEM = @@ -269,8 +271,8 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_SPI_CLK), // SPI Clk AGPIO(GPIO_SPI_CS), // SPI Chip Select AGPIO(GPIO_SPI_DC), // SPI Data Direction - AGPIO(GPIO_SSPI_MISO), // Software SPI Master Input Slave Output - AGPIO(GPIO_SSPI_MOSI), // Software SPI Master Output Slave Input + AGPIO(GPIO_SSPI_MISO), // Software SPI Master Input Client Output + AGPIO(GPIO_SSPI_MOSI), // Software SPI Master Output Client Input AGPIO(GPIO_SSPI_SCLK), // Software SPI Serial Clock AGPIO(GPIO_SSPI_CS), // Software SPI Chip Select AGPIO(GPIO_SSPI_DC), // Software SPI Data or Command @@ -293,6 +295,9 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_DSB), // Single wire DS18B20 or DS18S20 AGPIO(GPIO_DSB_OUT), // Pseudo Single wire DS18B20 or DS18S20 #endif +#ifdef USE_LMT01 + AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO +#endif // Light #ifdef USE_LIGHT @@ -468,11 +473,11 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_PN532_TXD), // PN532 HSU Tx AGPIO(GPIO_PN532_RXD), // PN532 HSU Rx #endif -#ifdef USE_TASMOTA_SLAVE - AGPIO(GPIO_TASMOTASLAVE_TXD), // Tasmota Slave TX - AGPIO(GPIO_TASMOTASLAVE_RXD), // Tasmota Slave RX - AGPIO(GPIO_TASMOTASLAVE_RST), // Tasmota Slave Reset - AGPIO(GPIO_TASMOTASLAVE_RST_INV), // Tasmota Slave Reset Inverted +#ifdef USE_TASMOTA_CLIENT + AGPIO(GPIO_TASMOTACLIENT_TXD), // Tasmota Client TX + AGPIO(GPIO_TASMOTACLIENT_RXD), // Tasmota Client RX + AGPIO(GPIO_TASMOTACLIENT_RST), // Tasmota Client Reset + AGPIO(GPIO_TASMOTACLIENT_RST_INV), // Tasmota Client Reset Inverted #endif #ifdef USE_RDM6300 AGPIO(GPIO_RDM6300_RX), @@ -622,20 +627,14 @@ typedef struct MYTMPLT { /********************************************************************************************/ // Supported hardware modules -enum SupportedModules { - WEMOS, ESP32_CAM_AITHINKER, - MAXMODULE}; +enum SupportedModules { WEMOS, ESP32_CAM_AITHINKER, MAXMODULE }; #define USER_MODULE 255 -const char kModuleNames[] PROGMEM = - "ESP32-DevKit|ESP32 Cam AiThinker"; +const char kModuleNames[] PROGMEM = "ESP32-DevKit|ESP32 Cam AiThinker"; // Default module settings -const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { - WEMOS, - ESP32_CAM_AITHINKER -}; +const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { WEMOS, ESP32_CAM_AITHINKER }; const mytmplt kModules PROGMEM = { // WEMOS - Espressif ESP32-DevKitC - Any ESP32 device like WeMos and NodeMCU hardware (ESP32) @@ -685,12 +684,12 @@ const mytmplt kModules PROGMEM = /*********************************************************************************************\ Known templates -{"NAME":"AITHINKER CAM","GPIO":[4992,65504,65504,65504,65504,5088,65504,65504,65504,65504,65504,65504,65504,65504,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,65504,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1} -{"NAME":"Olimex ESP32-PoE","GPIO":[65504,65504,65504,65504,65504,65504,0,0,5536,65504,65504,65504,65504,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,65504,65504,65504,65504,65504,0,0,65504],"FLAG":0,"BASE":1} +{"NAME":"AITHINKER CAM","GPIO":[4992,1,1,1,1,5088,1,1,1,1,1,1,1,1,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,1,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1} +{"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} +{"NAME":"wESP32","GPIO":[1,1,1,1,1,1,0,0,0,1,1,1,5568,5600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} \*********************************************************************************************/ - #endif // ESP32 #endif // _TASMOTA_TEMPLATE_ESP32_H_ diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index 69146852c..6b64471b0 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,7 +20,7 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x08030105; +const uint32_t VERSION = 0x08030106; // Lowest compatible version const uint32_t VERSION_COMPATIBLE = 0x07010006; diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 5313d8ffb..d18368431 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -44,7 +44,7 @@ const uint16_t HTTP_OTA_RESTART_RECONNECT_TIME = 28000; // milliseconds - Allow uint8_t *efm8bb1_update = nullptr; #endif // USE_RF_FLASH -enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1, UPL_TASMOTASLAVE }; +enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1, UPL_TASMOTACLIENT }; static const char * HEADER_KEYS[] = { "User-Agent", }; @@ -2022,8 +2022,8 @@ void ModuleSaveSettings(void) /*-------------------------------------------------------------------------------------------*/ -const char kUnescapeCode[] = "&><\"\'"; -const char kEscapeCode[] PROGMEM = "&|>|<|"|'"; +const char kUnescapeCode[] = "&><\"\'\\"; +const char kEscapeCode[] PROGMEM = "&|>|<|"|'|\"; String HtmlEscape(const String unescaped) { char escaped[10]; @@ -2327,22 +2327,6 @@ void OtherSaveSettings(void) } AddLog_P(LOG_LEVEL_INFO, message); -/* - // This sometimes provides intermittent watchdog - bool template_activate = Webserver->hasArg("t2"); // Try this to tackle intermittent watchdog after execution of Template command - WebGetArg("t1", tmp, sizeof(tmp)); - if (strlen(tmp)) { // {"NAME":"12345678901234","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":255,"BASE":255} - char svalue[128]; - snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_TEMPLATE " %s"), tmp); - ExecuteWebCommand(svalue, SRC_WEBGUI); - - if (template_activate) { - snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_MODULE " 0")); - ExecuteWebCommand(svalue, SRC_WEBGUI); - } - } - // Try async execution of commands -*/ WebGetArg("t1", tmp, sizeof(tmp)); if (strlen(tmp)) { // {"NAME":"12345678901234","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":255,"BASE":255} snprintf_P(message, sizeof(message), PSTR(D_CMND_BACKLOG " " D_CMND_TEMPLATE " %s%s"), tmp, (Webserver->hasArg("t2")) ? "; " D_CMND_MODULE " 0" : ""); @@ -2489,7 +2473,7 @@ void HandleInformation(void) #endif if (Settings.flag4.network_wifi) { int32_t rssi = WiFi.RSSI(); - WSContentSend_P(PSTR("}1" D_AP "%d " D_SSID " (" D_RSSI ")}2%s (%d%%, %d dBm)"), Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active), WifiGetRssiAsQuality(rssi), rssi); + WSContentSend_P(PSTR("}1" D_AP "%d " D_SSID " (" D_RSSI ")}2%s (%d%%, %d dBm)"), Settings.sta_active +1, HtmlEscape(SettingsText(SET_STASSID1 + Settings.sta_active)).c_str(), WifiGetRssiAsQuality(rssi), rssi); WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), my_hostname, (Mdns.begun) ? ".local" : ""); #if LWIP_IPV6 String ipv6_addr = WifiGetIPv6(); @@ -2508,7 +2492,7 @@ void HandleInformation(void) WSContentSend_P(PSTR("}1" D_SUBNET_MASK "}2%s"), IPAddress(Settings.ip_address[2]).toString().c_str()); WSContentSend_P(PSTR("}1" D_DNS_SERVER "}2%s"), IPAddress(Settings.ip_address[3]).toString().c_str()); } - if (static_cast(WiFi.softAPIP()) != 0) { + if ((WiFi.getMode() >= WIFI_AP) && (static_cast(WiFi.softAPIP()) != 0)) { WSContentSend_P(PSTR("}1
}2
")); WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.softAPmacAddress().c_str()); WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (AP)}2%s"), WiFi.softAPIP().toString().c_str()); @@ -2667,8 +2651,8 @@ void HandleUploadDone(void) WSContentSend_P(PSTR("%06x'>" D_SUCCESSFUL "
"), WebColor(COL_TEXT_SUCCESS)); WSContentSend_P(HTTP_MSG_RSTRT); ShowWebSource(SRC_WEBGUI); -#ifdef USE_TASMOTA_SLAVE - if (TasmotaSlave_GetFlagFlashing()) { +#ifdef USE_TASMOTA_CLIENT + if (TasmotaClient_GetFlagFlashing()) { restart_flag = 0; } else { // It was a normal firmware file, or we are ready to restart device restart_flag = 2; @@ -2681,9 +2665,9 @@ void HandleUploadDone(void) WSContentSend_P(PSTR("
")); WSContentSpaceButton(BUTTON_MAIN); WSContentStop(); -#ifdef USE_TASMOTA_SLAVE - if (TasmotaSlave_GetFlagFlashing()) { - TasmotaSlave_Flash(); +#ifdef USE_TASMOTA_CLIENT + if (TasmotaClient_GetFlagFlashing()) { + TasmotaClient_Flash(); } #endif } @@ -2753,11 +2737,11 @@ void HandleUploadLoop(void) if (Web.upload_error != 0) { return; } } else #endif // USE_RF_FLASH -#ifdef USE_TASMOTA_SLAVE - if ((WEMOS == my_module_type) && (upload.buf[0] == ':')) { // Check if this is a ARDUINO SLAVE hex file +#ifdef USE_TASMOTA_CLIENT + if ((WEMOS == my_module_type) && (upload.buf[0] == ':')) { // Check if this is a ARDUINO CLIENT hex file Update.end(); // End esp8266 update session - Web.upload_file_type = UPL_TASMOTASLAVE; - Web.upload_error = TasmotaSlave_UpdateInit(); // 0 + Web.upload_file_type = UPL_TASMOTACLIENT; + Web.upload_error = TasmotaClient_UpdateInit(); // 0 if (Web.upload_error != 0) { return; } } else #endif @@ -2821,9 +2805,9 @@ void HandleUploadLoop(void) } } #endif // USE_RF_FLASH -#ifdef USE_TASMOTA_SLAVE - else if (UPL_TASMOTASLAVE == Web.upload_file_type) { - TasmotaSlave_WriteBuffer(upload.buf, upload.currentSize); +#ifdef USE_TASMOTA_CLIENT + else if (UPL_TASMOTACLIENT == Web.upload_file_type) { + TasmotaClient_WriteBuffer(upload.buf, upload.currentSize); } #endif else { // firmware @@ -2887,10 +2871,10 @@ void HandleUploadLoop(void) Web.upload_file_type = UPL_TASMOTA; } #endif // USE_RF_FLASH -#ifdef USE_TASMOTA_SLAVE - else if (UPL_TASMOTASLAVE == Web.upload_file_type) { +#ifdef USE_TASMOTA_CLIENT + else if (UPL_TASMOTACLIENT == Web.upload_file_type) { // Done writing the hex to SPI flash - TasmotaSlave_SetFlagFlashing(true); // So we know on upload success page if it needs to flash hex or do a normal restart + TasmotaClient_SetFlagFlashing(true); // So we know on upload success page if it needs to flash hex or do a normal restart Web.upload_file_type = UPL_TASMOTA; } #endif diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 208f7211c..921433a6d 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -397,7 +397,7 @@ void ScriptEverySecond(void) { if (bitRead(Settings.rule_enabled, 0)) { struct T_INDEX *vtp=glob_script_mem.type; - float delta=(millis()-script_lastmillis)/1000; + float delta=(millis()-script_lastmillis)/1000.0; script_lastmillis=millis(); for (uint8_t count=0; counttype == KNX_SCENE) { + // VALUE + uint8_t tempvar = knx.data_to_1byte_uint(msg.data); + dtostrfd(tempvar,2,tempchar); + } else { // VALUE float tempvar = knx.data_to_2byte_float(msg.data); dtostrfd(tempvar,2,tempchar); @@ -602,6 +612,18 @@ void KNX_CB_Action(message_t const &msg, void *arg) } } } + else if (chan->type == KNX_SCENE) // KNX RX SCENE SLOT (write command) + { + if (!toggle_inhibit) { + char command[25]; + // Value received + snprintf_P(command, sizeof(command), PSTR("event KNX_SCENE=%s"), tempchar); + ExecuteCommand(command, SRC_KNX); + if (Settings.flag.knx_enable_enhancement) { + toggle_inhibit = TOGGLE_INHIBIT_TIME; + } + } + } #endif break; @@ -1054,6 +1076,31 @@ void CmndKnxTxVal(void) } } +void CmndKnxTxScene(void) +{ + if ( (XdrvMailbox.data_len > 0) && Settings.flag.knx_enabled ) { + // XdrvMailbox.payload <- scene number to send + uint8_t i = KNX_GA_Search(KNX_SCENE); + if ( i != KNX_Empty ) { + KNX_addr.value = Settings.knx_GA_addr[i]; + + uint8_t tempvar = TextToInt(XdrvMailbox.data); + dtostrfd(tempvar,0,XdrvMailbox.data); + + knx.write_1byte_uint(KNX_addr, tempvar); + if (Settings.flag.knx_enable_enhancement) { + knx.write_1byte_uint(KNX_addr, tempvar); + knx.write_1byte_uint(KNX_addr, tempvar); + } + + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s = %s " D_SENT_TO " %d.%d.%d"), + device_param_ga[KNX_SCENE-1], XdrvMailbox.data, + KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member); + ResponseCmndIdxChar (XdrvMailbox.data); + } + } +} + void CmndKnxEnabled(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino index 70ab6d620..476d45765 100644 --- a/tasmota/xdrv_12_home_assistant.ino +++ b/tasmota/xdrv_12_home_assistant.ino @@ -27,14 +27,14 @@ const char kHAssJsonSensorTypes[] PROGMEM = D_JSON_APPARENT_POWERUSAGE "|Battery|" D_JSON_CURRENT "|" D_JSON_DISTANCE "|" D_JSON_FREQUENCY "|" D_JSON_HUMIDITY "|" D_JSON_ILLUMINANCE "|" D_JSON_MOISTURE "|PB0.3|PB0.5|PB1|PB2.5|PB5|PB10|PM1|PM2.5|PM10|" D_JSON_POWERFACTOR "|" D_JSON_POWERUSAGE "|" D_JSON_TOTAL_START_TIME "|" D_JSON_REACTIVE_POWERUSAGE "|" D_JSON_TODAY "|" D_JSON_TOTAL "|" D_JSON_VOLTAGE "|" D_JSON_WEIGHT "|" D_JSON_YESTERDAY "|" - D_JSON_CO2 "|" D_JSON_ECO2 "|" D_JSON_TVOC "|"; + D_JSON_CO2 "|" D_JSON_ECO2 "|" D_JSON_TVOC "|" D_COLOR_RED "|" D_COLOR_GREEN "|" D_COLOR_BLUE"|" D_CCT "|" D_PROXIMITY "|Ambient|"; const char kHAssJsonSensorUnits[] PROGMEM = "||||" "VA|%|A|Cm|Hz|%|LX|" "%|ppd|ppd|ppd|ppd|ppd|ppd|µg/m³|µg/m³|µg/m³|Cos φ|W| |" "VAr|kWh|kWh|V|Kg|kWh|" - "ppm|ppm|ppb|"; + "ppm|ppm|ppb|R|G|B|" D_UNIT_KELVIN "| |LX|"; const char kHAssJsonSensorDevCla[] PROGMEM = "dev_cla\":\"temperature|ic\":\"mdi:weather-rainy|dev_cla\":\"pressure|dev_cla\":\"pressure|" @@ -42,61 +42,64 @@ const char kHAssJsonSensorDevCla[] PROGMEM = "ic\":\"mdi:cup-water|ic\":\"mdi:flask|ic\":\"mdi:flask|ic\":\"mdi:flask|ic\":\"mdi:flask|ic\":\"mdi:flask|ic\":\"mdi:flask|" "ic\":\"mdi:air-filter|ic\":\"mdi:air-filter|ic\":\"mdi:air-filter|ic\":\"mdi:alpha-f-circle-outline|dev_cla\":\"power|ic\":\"mdi:progress-clock|" "dev_cla\":\"power|dev_cla\":\"power|dev_cla\":\"power|ic\":\"mdi:alpha-v-circle-outline|ic\":\"mdi:scale|dev_cla\":\"power|" - "ic\":\"mdi:periodic-table-co2|ic\":\"mdi:air-filter|ic\":\"mdi:periodic-table-co2|"; + "ic\":\"mdi:periodic-table-co2|ic\":\"mdi:air-filter|ic\":\"mdi:periodic-table-co2|" + "ic\":\"mdi:palette|ic\":\"mdi:palette|ic\":\"mdi:palette|ic\":\"mdi:temperature-kelvin|ic\":\"mdi:ruler|dev_cla\":\"illuminance|"; //"ic\":\"mdi:weather-windy|ic\":\"mdi:weather-windy|ic\":\"mdi:weather-windy|ic\":\"mdi:weather-windy|" // List of sensors ready for discovery -const char HASS_DISCOVER_SENSOR[] PROGMEM = - ",\"unit_of_meas\":\"%s\",\"%s\"," // unit of measure and class (or icon) - "\"frc_upd\":true," // force update for better graph representation - "\"val_tpl\":\"{{value_json['%s']['%s']"; // "COUNTER":{"C1":0} -> {{ value_json['COUNTER']['C1'] - const char HASS_DISCOVER_BASE[] PROGMEM = - "{\"name\":\"%s\"," // dualr2 1 - "\"stat_t\":\"%s\"," // stat/dualr2/RESULT (implies "\"optimistic\":\"false\",") - "\"avty_t\":\"%s\"," // tele/dualr2/LWT - "\"pl_avail\":\"" D_ONLINE "\"," // Online - "\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline + "{\"name\":\"%s\"," // dualr2 1 + "\"stat_t\":\"%s\""; // stat/dualr2/RESULT (implies "\"optimistic\":\"false\",") + +const char HASS_DISCOVER_SENSOR[] PROGMEM = + ",\"unit_of_meas\":\"%s\",\"%s\"," // unit of measure and class (or icon) + "\"frc_upd\":true," // force update for better graph representation + "\"val_tpl\":\"{{value_json['%s']['%s']"; // "COUNTER":{"C1":0} -> {{ value_json['COUNTER']['C1'] + +const char HASS_DISCOVER_SENSOR_LWT[] PROGMEM = + ",\"avty_t\":\"%s\"," // tele/dualr2/LWT + "\"pl_avail\":\"" D_ONLINE "\"," // Online + "\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline const char HASS_DISCOVER_RELAY[] PROGMEM = - ",\"cmd_t\":\"%s\"," // cmnd/dualr2/POWER2 - "\"val_tpl\":\"{{value_json.%s}}\"," // POWER2 - "\"pl_off\":\"%s\"," // OFF - "\"pl_on\":\"%s\""; // ON + ",\"cmd_t\":\"%s\"," // cmnd/dualr2/POWER2 + "\"val_tpl\":\"{{value_json.%s}}\"," // POWER2 + "\"pl_off\":\"%s\"," // OFF + "\"pl_on\":\"%s\""; // ON const char HASS_DISCOVER_BIN_SWITCH[] PROGMEM = - ",\"val_tpl\":\"{{value_json.%s}}\"," // STATE - "\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work - "\"pl_on\":\"%s\"," // ON - "\"pl_off\":\"%s\""; // OFF + ",\"val_tpl\":\"{{value_json.%s}}\"," // STATE + "\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work + "\"pl_on\":\"%s\"," // ON + "\"pl_off\":\"%s\""; // OFF const char HASS_DISCOVER_BIN_PIR[] PROGMEM = - ",\"val_tpl\":\"{{value_json.%s}}\"," // STATE - "\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work - "\"pl_on\":\"%s\"," // ON - "\"off_dly\":1"; // Switchmode13 and Switchmode14 doesn't transmit an OFF state. + ",\"val_tpl\":\"{{value_json.%s}}\"," // STATE + "\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work + "\"pl_on\":\"%s\"," // ON + "\"off_dly\":1"; // Switchmode13 and Switchmode14 doesn't transmit an OFF state. const char HASS_DISCOVER_BASE_LIGHT[] PROGMEM = - ",\"bri_cmd_t\":\"%s\"," // cmnd/led2/Dimmer - "\"bri_stat_t\":\"%s\"," // stat/led2/RESULT - "\"bri_scl\":100," // 100% - "\"on_cmd_type\":\"%s\"," // power on (first), power on (last), no power on (brightness) + ",\"bri_cmd_t\":\"%s\"," // cmnd/led2/Dimmer + "\"bri_stat_t\":\"%s\"," // stat/led2/RESULT + "\"bri_scl\":100," // 100% + "\"on_cmd_type\":\"%s\"," // power on (first), power on (last), no power on (brightness) "\"bri_val_tpl\":\"{{value_json.%s}}\""; const char HASS_DISCOVER_LIGHT_COLOR[] PROGMEM = - ",\"rgb_cmd_t\":\"%s2\"," // cmnd/led2/Color2 - "\"rgb_stat_t\":\"%s\"," // stat/led2/RESULT + ",\"rgb_cmd_t\":\"%s2\"," // cmnd/led2/Color2 + "\"rgb_stat_t\":\"%s\"," // stat/led2/RESULT "\"rgb_val_tpl\":\"{{value_json." D_CMND_COLOR ".split(',')[0:3]|join(',')}}\""; const char HASS_DISCOVER_LIGHT_WHITE[] PROGMEM = - ",\"whit_val_cmd_t\":\"%s\"," // cmnd/led2/White - "\"whit_val_stat_t\":\"%s\"," // stat/led2/RESULT + ",\"whit_val_cmd_t\":\"%s\"," // cmnd/led2/White + "\"whit_val_stat_t\":\"%s\"," // stat/led2/RESULT "\"whit_val_scl\":100," "\"whit_val_tpl\":\"{{value_json.Channel[3]}}\""; const char HASS_DISCOVER_LIGHT_CT[] PROGMEM = - ",\"clr_temp_cmd_t\":\"%s\"," // cmnd/led2/CT - "\"clr_temp_stat_t\":\"%s\"," // stat/led2/RESULT + ",\"clr_temp_cmd_t\":\"%s\"," // cmnd/led2/CT + "\"clr_temp_stat_t\":\"%s\"," // stat/led2/RESULT "\"clr_temp_val_tpl\":\"{{value_json." D_CMND_COLORTEMPERATURE "}}\""; const char HASS_DISCOVER_LIGHT_SCHEME[] PROGMEM = @@ -141,7 +144,7 @@ const char kHAssTriggerStringButtons[] PROGMEM = "|SINGLE|DOUBLE|TRIPLE|QUAD|PENTA|HOLD|"; const char kHAssError1[] PROGMEM = - "HASS: MQTT discovery failed due to too long topic or friendly name. Please shorten topic and/or friendly name. Failed to format"; + "HASS: MQTT discovery failed due to too long topic or device/friendly name. Please shorten topic and/or device/friendly name. Failed to format"; const char kHAssError2[] PROGMEM = "HASS: The configuration of the Relays is wrong, there is a Light that is using an index higher than the number of the validated relay.\n " @@ -195,13 +198,22 @@ void HAssAnnounceRelayLight(void) bool ct_light = false; // Controls a CT Light when SetOption37 is >= 128 bool wt_light = false; // Controls a White Light when SetOption37 is >= 128 bool err_flag = false; // When true it blocks the creation of entities if the order of the Relays is not correct to avoid issue with Lights + bool TuyaMod = false; // Controls Tuya MCU modules bool PwmMod = false; // Controls PWM_DIMMER module + bool FanMod = false; // Controls SONOFF_IFAN0X modules uint8_t dimmer = 1; + uint8_t valid_relay = 0; uint8_t max_lights = 1; + uint8_t TuyaRel = 0; + uint8_t TuyaRelInv = 0; + uint8_t TuyaDim = 0; #ifdef ESP8266 - if (PWM_DIMMER == my_module_type) { PwmMod = true; } + if (PWM_DIMMER == my_module_type ) { PwmMod = true; } // + if (SONOFF_IFAN02 == my_module_type || SONOFF_IFAN03 == my_module_type) { FanMod = true; } + if (SONOFF_DUAL == my_module_type) { valid_relay = 2; } + if (TUYA_DIMMER == my_module_type || SK03_TUYA == my_module_type) { TuyaMod = true; } #endif //ESP8266 // If there is a special Light to be enabled and managed with SetOption68 or SetOption37 >= 128, Discovery calculates the maximum number of entities to be generated in advance @@ -209,17 +221,21 @@ void HAssAnnounceRelayLight(void) if (PwmMulti) { max_lights = Light.subtype; } if (!LightControl) { - ind_light = 1; + ind_light = true; if (!PwmMulti) { max_lights = 2;} } - // Lights types: 0 = LST_NONE / 1 = LST_SINGLE / 2 = LST_COLDWARM / 3 = LST_RGB / 4 = LST_RGBW / 5 = LST_RGBCW - for (uint32_t i = 1; i <= MAX_RELAYS; i++) { - bool RelayX = PinUsed(GPIO_REL1 +i-1); - is_topic_light = Settings.flag.hass_light && RelayX || light_type && !RelayX || PwmMod; // SetOption30 - Enforce HAss autodiscovery as light +#ifdef USE_TUYA_MCU + TuyaRel = TuyaGetDpId((TUYA_MCU_FUNC_REL1+ i-1) + active_device - 1); + TuyaRelInv = TuyaGetDpId((TUYA_MCU_FUNC_REL1_INV+ i-1) + active_device - 1); + TuyaDim = TuyaGetDpId((TUYA_MCU_FUNC_DIMMER) + active_device - 1); +#endif //USE_TUYA_MCU + + bool RelayX = PinUsed(GPIO_REL1 +i-1) || (valid_relay >= i) || (TuyaRel > 0 && TuyaMod) || (TuyaRelInv > 0 && TuyaMod); // Check if the gpio is configured as Relay or force it for Sonoff DUAL R1 with MCU and Tuya MCU + is_topic_light = Settings.flag.hass_light && RelayX || light_type && !RelayX || PwmMod || (TuyaDim > 0 && TuyaMod); // SetOption30 - Enforce HAss autodiscovery as light mqtt_data[0] = '\0'; // Clear retained message // Clear "other" topic first in case the device has been reconfigured from light to switch or vice versa @@ -255,13 +271,14 @@ void HAssAnnounceRelayLight(void) GetTopic_P(command_topic, CMND, mqtt_topic, value_template); GetTopic_P(state_topic, TELE, mqtt_topic, D_RSLT_STATE); GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT); - Response_P(HASS_DISCOVER_BASE, name, state_topic, availability_topic); + Response_P(HASS_DISCOVER_BASE, name, state_topic); + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); TryResponseAppend_P(HASS_DISCOVER_RELAY, command_topic, value_template, SettingsText(SET_STATE_TXT1), SettingsText(SET_STATE_TXT2)); TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP_getChipId()); #ifdef USE_LIGHT if (i >= Light.device) { - if (!RelayX || PwmMod) { + if (!RelayX || PwmMod || (TuyaDim > 0 && TuyaMod)) { char *brightness_command_topic = stemp1; strncpy_P(stemp3, Settings.flag.not_power_linked ? PSTR("last") : PSTR("brightness"), sizeof(stemp3)); // SetOption20 - Control power in relation to Dimmer/Color/Ct changes char channel_num[9]; @@ -411,6 +428,14 @@ void HAssAnnouncerBinSensors(uint8_t device, uint8_t present, uint8_t dual, uint TryResponseAppend_P(HASS_DISCOVER_BIN_PIR, PSTR(D_RSLT_STATE), SettingsText(SET_STATE_TXT2)); } TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP_getChipId()); +#ifdef DEEPSLEEP_LWT_HA_DISCOVERY + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); +#else + if (Settings.deepsleep == 0) + { + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); + } +#endif //DEEPSLEEP_LWT_HA_DISCOVERY TryResponseAppend_P(PSTR("}")); } } @@ -505,7 +530,7 @@ void HAssAnnounceButtons(void) { button_present = 1; } else -#endif +#endif // ESP8266 { if (PinUsed(GPIO_KEY1, button_index)) { button_present = 1; @@ -557,12 +582,21 @@ void HAssAnnounceSensor(const char *sensorname, const char *subsensortype, const char prefix[TOPSZ]; char *state_topic = stemp1; char *availability_topic = stemp2; + //bool LwtSensor = MQTT_LWT_DISCOVERY; GetTopic_P(state_topic, TELE, mqtt_topic, PSTR(D_RSLT_SENSOR)); snprintf_P(name, sizeof(name), PSTR("%s %s %s"), SettingsText(SET_DEVICENAME), sensorname, MultiSubName); GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT); - Response_P(HASS_DISCOVER_BASE, name, state_topic, availability_topic); + Response_P(HASS_DISCOVER_BASE, name, state_topic); + #ifdef DEEPSLEEP_LWT_HA_DISCOVERY + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); +#else + if (Settings.deepsleep == 0) + { + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); + } +#endif //DEEPSLEEP_LWT_HA_DISCOVERY TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP_getChipId()); @@ -629,8 +663,8 @@ void HAssAnnounceSensors(void) sensordata[0] = '{'; snprintf_P(sensordata, sizeof(sensordata), PSTR("%s}"), sensordata); // {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}} // USE THE FOLLOWING LINE TO TEST JSON - //snprintf_P(sensordata, sizeof(sensordata), PSTR("{\"HX711\":{\"Weight\":[22,34,1023.4]}}")); - + //snprintf_P(sensordata, sizeof(sensordata), PSTR("{\"APDS9960\":{\"Red\":282,\"Green\":252,\"Blue\":196,\"Ambient\":169,\"CCT\":4217,\"Proximity\":9}}")); + //snprintf_P(sensordata, sizeof(sensordata), PSTR("{\"ENERGY\":{\"TotalStartTime\":\"2018-11-23T15:33:47\",\"Total\":0.017,\"TotalTariff\":[0.000,0.017],\"Yesterday\":0.000,\"Today\":0.002,\"ExportActive\":0.000,\"ExportTariff\":[0.000,0.000],\"Period\":0.00,\"Power\":0.00,\"ApparentPower\":7.84,\"ReactivePower\":-7.21,\"Factor\":0.39,\"Frequency\":50.0,\"Voltage\":234.31,\"Current\":0.039,\"ImportActive\":12.580,\"ImportReactive\":0.002,\"ExportReactive\":39.131,\"PhaseAngle\":290.45}}")); StaticJsonBuffer<500> jsonBuffer; JsonObject &root = jsonBuffer.parseObject(sensordata); @@ -703,7 +737,8 @@ void HAssAnnounceDeviceInfoAndStatusSensor(void) GetTopic_P(state_topic, TELE, mqtt_topic, PSTR(D_RSLT_HASS_STATE)); GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT); - Response_P(HASS_DISCOVER_BASE, name, state_topic, availability_topic); + Response_P(HASS_DISCOVER_BASE, name, state_topic); + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); TryResponseAppend_P(HASS_DISCOVER_SENSOR_HASS_STATUS, state_topic); TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO, unique_id, ESP_getChipId(), SettingsText(SET_DEVICENAME), ModuleName().c_str(), my_version, my_image); @@ -719,7 +754,7 @@ void HAssPublishStatus(void) "\"" D_CMND_IPADDRESS "\":\"%s\",\"" D_JSON_RSSI "\":\"%d\",\"" D_JSON_SIGNAL " (dBm)""\":\"%d\"," "\"WiFi " D_JSON_LINK_COUNT "\":%d,\"WiFi " D_JSON_DOWNTIME "\":\"%s\",\"" D_JSON_MQTT_COUNT "\":%d,\"LoadAvg\":%lu}"), my_version, my_image, GetBuildDateAndTime().c_str(), ModuleName().c_str(), GetResetReason().c_str(), - GetUptime().c_str(), NetworkHostname(), WiFi.localIP().toString().c_str(), WifiGetRssiAsQuality(WiFi.RSSI()), + GetUptime().c_str(), my_hostname, WiFi.localIP().toString().c_str(), WifiGetRssiAsQuality(WiFi.RSSI()), WiFi.RSSI(), WifiLinkCount(), WifiDowntime().c_str(), MqttConnectCount(), loop_load_avg); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_HASS_STATE)); } @@ -812,7 +847,6 @@ void HAssAnyKey(void) bool Xdrv12(uint8_t function) { bool result = false; - if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT switch (function) @@ -844,10 +878,13 @@ bool Xdrv12(uint8_t function) case FUNC_MQTT_INIT: hass_mode = 0; // Discovery only if Settings.flag.hass_discovery is set hass_init_step = 2; // Delayed discovery + // if (!Settings.flag.hass_discovery) { + // AddLog_P2(LOG_LEVEL_INFO, PSTR("MQT: homeassistant/49A3BC/Discovery = {\"dev\":{\"ids\":[\"49A3BC\"]},\"cmd_t\":\"cmnd/test1/\",\"Discovery\":0}")); + // } break; } } return result; } -#endif // USE_HOME_ASSISTANT +#endif // USE_HOME_ASSISTANT \ No newline at end of file diff --git a/tasmota/xdrv_23_zigbee_0_constants.ino b/tasmota/xdrv_23_zigbee_0_constants.ino index 57bf22499..92e88c708 100644 --- a/tasmota/xdrv_23_zigbee_0_constants.ino +++ b/tasmota/xdrv_23_zigbee_0_constants.ino @@ -19,6 +19,13 @@ #ifdef USE_ZIGBEE +#if defined(USE_ZIGBEE_ZNP) && defined(USE_ZIGBEE_EZSP) + #error "#define USE_ZIGBEE_ZNP and #define USE_ZIGBEE_EZSP are mutually incompatible" +#endif +#if !defined(USE_ZIGBEE_ZNP) && !defined(USE_ZIGBEE_EZSP) + #error "You must select one of: #define USE_ZIGBEE_ZNP or #define USE_ZIGBEE_EZSP" +#endif + #define OCCUPANCY "Occupancy" // global define for Aqara typedef uint64_t Z_IEEEAddress; @@ -26,6 +33,7 @@ typedef uint16_t Z_ShortAddress; const uint16_t BAD_SHORTADDR = 0xFFFE; +#ifdef USE_ZIGBEE_ZNP enum ZnpCommandType { Z_POLL = 0x00, Z_SREQ = 0x20, @@ -45,6 +53,7 @@ enum ZnpSubsystem { Z_DEBUG = 0x08, Z_APP = 0x09 }; +#endif // USE_ZIGBEE_ZNP // Commands in the SYS subsystem enum SysCommand { diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index 4297a4375..cbfe822ab 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -168,6 +168,8 @@ SBuffer *zigbee_buffer = nullptr; #define USE_ZIGBEE_CHANNEL_MASK (1 << (USE_ZIGBEE_CHANNEL)) +#ifdef USE_ZIGBEE_ZNP + // ZBS_* Zigbee Send // ZBR_* Zigbee Recv ZBM(ZBS_RESET, Z_AREQ | Z_SYS, SYS_RESET, 0x00 ) // 410001 SYS_RESET_REQ Hardware reset @@ -611,6 +613,30 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_STOP(ZIGBEE_LABEL_ABORT) }; +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP + +// Update the relevant commands with Settings +void Z_UpdateConfig(uint8_t zb_channel, uint16_t zb_pan_id, uint64_t zb_ext_panid, uint64_t zb_precfgkey_l, uint64_t zb_precfgkey_h) { +} + + +static const Zigbee_Instruction zb_prog[] PROGMEM = { + ZI_LABEL(0) + ZI_NOOP() + ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) + ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_ABORT) + // ZI_ON_RECV_UNEXPECTED(&Z_Recv_Default) + // ZI_WAIT(10500) // wait for 10 seconds for Tasmota to stabilize + + ZI_LABEL(ZIGBEE_LABEL_MAIN_LOOP) + ZI_WAIT_FOREVER() + ZI_GOTO(ZIGBEE_LABEL_READY) +}; + +#endif // USE_ZIGBEE_EZSP + uint8_t ZigbeeGetInstructionSize(uint8_t instr) { // in Zigbee_Instruction lines (words) if (instr >= ZGB_INSTR_12_BYTES) { return 3; @@ -770,7 +796,9 @@ void ZigbeeStateMachine_Run(void) { } break; case ZGB_INSTR_SEND: +#ifdef USE_ZIGBEE_ZNP ZigbeeZNPSend((uint8_t*) cur_ptr1, cur_d8 /* len */); +#endif // USE_ZIGBEE_ZNP break; case ZGB_INSTR_WAIT_UNTIL: zigbee.recv_until = true; // and reuse ZGB_INSTR_WAIT_RECV diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 53590a4c4..7e9129d64 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -552,6 +552,7 @@ int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) { return -1; } +#ifdef USE_ZIGBEE_ZNP /*********************************************************************************************\ * Send specific ZNP messages \*********************************************************************************************/ @@ -589,6 +590,32 @@ void Z_SendAFInfoRequest(uint16_t shortaddr) { ZigbeeZNPSend(AFInfoReq, sizeof(AFInfoReq)); } +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP +/*********************************************************************************************\ + * Send specific EZS¨ messages +\*********************************************************************************************/ + +// +// Send ZDO_IEEE_ADDR_REQ request to get IEEE long address +// +void Z_SendIEEEAddrReq(uint16_t shortaddr) { +} + +// +// Send ACTIVE_EP_REQ to collect active endpoints for this address +// +void Z_SendActiveEpReq(uint16_t shortaddr) { +} + +// +// Send AF Info Request +// +void Z_SendAFInfoRequest(uint16_t shortaddr) { +} + +#endif // USE_ZIGBEE_EZSP /*********************************************************************************************\ * Callbacks @@ -718,6 +745,8 @@ typedef struct Z_Dispatcher { ZB_RecvMsgFunc func; } Z_Dispatcher; +#ifdef USE_ZIGBEE_ZNP + // Ffilters based on ZNP frames ZBM(AREQ_AF_DATA_CONFIRM, Z_AREQ | Z_AF, AF_DATA_CONFIRM) // 4480 ZBM(AREQ_AF_INCOMING_MESSAGE, Z_AREQ | Z_AF, AF_INCOMING_MSG) // 4481 @@ -767,6 +796,8 @@ int32_t Z_Recv_Default(int32_t res, const class SBuffer &buf) { } } +#endif // USE_ZIGBEE_ZNP + /*********************************************************************************************\ * Functions called by State Machine \*********************************************************************************************/ diff --git a/tasmota/xdrv_23_zigbee_9_impl.ino b/tasmota/xdrv_23_zigbee_9_impl.ino index 4da0a48f6..1cc5f6efc 100644 --- a/tasmota/xdrv_23_zigbee_9_impl.ino +++ b/tasmota/xdrv_23_zigbee_9_impl.ino @@ -21,18 +21,32 @@ #define XDRV_23 23 +#ifdef USE_ZIGBEE_ZNP const uint32_t ZIGBEE_BUFFER_SIZE = 256; // Max ZNP frame is SOF+LEN+CMD1+CMD2+250+FCS = 255 const uint8_t ZIGBEE_SOF = 0xFE; const uint8_t ZIGBEE_SOF_ALT = 0xFF; +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP +const uint32_t ZIGBEE_BUFFER_SIZE = 256; +const uint8_t ZIGBEE_EZSP_CANCEL = 0x1A; // cancel byte +const uint8_t ZIGBEE_EZSP_EOF = 0x7E; // end of frame +const uint8_t ZIGBEE_EZSP_ESCAPE = 0x7D; // escape byte +#endif // USE_ZIGBEE_EZSP #include TasmotaSerial *ZigbeeSerial = nullptr; const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix - D_CMND_ZIGBEEZNPSEND "|" D_CMND_ZIGBEE_PERMITJOIN "|" - D_CMND_ZIGBEE_STATUS "|" D_CMND_ZIGBEE_RESET "|" D_CMND_ZIGBEE_SEND "|" - D_CMND_ZIGBEE_PROBE "|" D_CMND_ZIGBEEZNPRECEIVE "|" +#ifdef USE_ZIGBEE_ZNP + D_CMND_ZIGBEEZNPSEND "|" D_CMND_ZIGBEEZNPRECEIVE "|" +#endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + D_CMND_ZIGBEE_EZSP_SEND "|" D_CMND_ZIGBEE_EZSP_RECEIVE "|" +#endif // USE_ZIGBEE_EZSP + D_CMND_ZIGBEE_PERMITJOIN "|" + D_CMND_ZIGBEE_STATUS "|" D_CMND_ZIGBEE_RESET "|" D_CMND_ZIGBEE_SEND "|" D_CMND_ZIGBEE_PROBE "|" D_CMND_ZIGBEE_FORGET "|" D_CMND_ZIGBEE_SAVE "|" D_CMND_ZIGBEE_NAME "|" D_CMND_ZIGBEE_BIND "|" D_CMND_ZIGBEE_UNBIND "|" D_CMND_ZIGBEE_PING "|" D_CMND_ZIGBEE_MODELID "|" D_CMND_ZIGBEE_LIGHT "|" D_CMND_ZIGBEE_RESTORE "|" D_CMND_ZIGBEE_BIND_STATE "|" @@ -40,9 +54,14 @@ const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix ; void (* const ZigbeeCommand[])(void) PROGMEM = { - &CmndZbZNPSend, &CmndZbPermitJoin, - &CmndZbStatus, &CmndZbReset, &CmndZbSend, - &CmndZbProbe, &CmndZbZNPReceive, +#ifdef USE_ZIGBEE_ZNP + &CmndZbZNPSend, &CmndZbZNPReceive, +#endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + &CmndZbEZSPSend, &CmndZbEZSPReceive, +#endif // USE_ZIGBEE_EZSP + &CmndZbPermitJoin, + &CmndZbStatus, &CmndZbReset, &CmndZbSend, &CmndZbProbe, &CmndZbForget, &CmndZbSave, &CmndZbName, &CmndZbBind, &CmndZbUnbind, &CmndZbPing, &CmndZbModelId, &CmndZbLight, &CmndZbRestore, &CmndZbBindState, @@ -52,11 +71,12 @@ void (* const ZigbeeCommand[])(void) PROGMEM = { // // Called at event loop, checks for incoming data from the CC2530 // -void ZigbeeInputLoop(void) -{ - static uint32_t zigbee_polling_window = 0; +void ZigbeeInputLoop(void) { + +#ifdef USE_ZIGBEE_ZNP + static uint32_t zigbee_polling_window = 0; // number of milliseconds since first byte static uint8_t fcs = ZIGBEE_SOF; - static uint32_t zigbee_frame_len = 5; // minimal zigbee frame lenght, will be updated when buf[1] is read + static uint32_t zigbee_frame_len = 5; // minimal zigbee frame length, will be updated when buf[1] is read // Receive only valid ZNP frames: // 00 - SOF = 0xFE // 01 - Length of Data Field - 0..250 @@ -140,6 +160,127 @@ void ZigbeeInputLoop(void) } zigbee_buffer->setLen(0); // empty buffer } +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP + static uint32_t zigbee_polling_window = 0; // number of milliseconds since first byte + bool escape = false; // was the previous byte an escape? + bool frame_complete = false; // frame is ready and complete + // Receive only valid EZSP frames: + // 1A - Cancel - cancel all previous bytes + // 7D - Escape byte - following byte is escaped + // 7E - end of frame + + while (ZigbeeSerial->available()) { + yield(); + uint8_t zigbee_in_byte = ZigbeeSerial->read(); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x%02X len=%d"), zigbee_in_byte, zigbee_buffer->len()); + + // if (0 == zigbee_buffer->len()) { // make sure all variables are correctly initialized + // escape = false; + // frame_complete = false; + // } + + if ((0x11 == zigbee_in_byte) || (0x13 == zigbee_in_byte)) { + continue; // ignore reserved bytes XON/XOFF + } + + if (ZIGBEE_EZSP_ESCAPE == zigbee_in_byte) { + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: Escape byte received")); + escape = true; + continue; + } + + if (ZIGBEE_EZSP_CANCEL == zigbee_in_byte) { + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x1A, cancel byte received, discarding %d bytes"), zigbee_buffer->len()); + zigbee_buffer->setLen(0); // empty buffer + escape = false; + frame_complete = false; + continue; // re-loop + } + + if (ZIGBEE_EZSP_EOF == zigbee_in_byte) { + // end of frame + frame_complete = true; + break; + } + + if (zigbee_buffer->len() < ZIGBEE_BUFFER_SIZE) { + if (escape) { + // invert bit 5 + zigbee_in_byte ^= 0x20; + escape = false; + } + + zigbee_buffer->add8(zigbee_in_byte); + zigbee_polling_window = millis(); // Wait for more data + } // adding bytes + } // while (ZigbeeSerial->available()) + + uint32_t frame_len = zigbee_buffer->len(); + if (frame_complete || (frame_len && (millis() > (zigbee_polling_window + ZIGBEE_POLLING)))) { + char hex_char[frame_len * 2 + 2]; + ToHex_P((unsigned char*)zigbee_buffer->getBuffer(), zigbee_buffer->len(), hex_char, sizeof(hex_char)); + + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Bytes follow_read_metric = %0d"), ZigbeeSerial->getLoopReadMetric()); + if ((frame_complete) && (frame_len >= 3)) { + // frame received and has at least 3 bytes (without EOF), checking CRC + // AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": received raw frame %s"), hex_char); + uint16_t crc = 0xFFFF; // frame CRC + // compute CRC + for (uint32_t i=0; iget8(i) << 8); + for (uint32_t i=0; i<8; i++) { + if (crc & 0x8000) { + crc = (crc << 1) ^ 0x1021; // polynom is x^16 + x^12 + x^5 + 1, CCITT standard + } else { + crc <<= 1; + } + } + } + + uint16_t crc_received = zigbee_buffer->get8(frame_len - 2) << 8 | zigbee_buffer->get8(frame_len - 1); + // remove 2 last bytes + + if (crc_received != crc) { + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": bad crc (received 0x%04X, computed 0x%04X) %s"), crc_received, crc, hex_char); + } else { + // copy buffer + SBuffer ezsp_buffer = zigbee_buffer->subBuffer(0, frame_len - 2); // CRC + + // CRC is correct, apply de-stuffing if DATA frame + if (0 == (ezsp_buffer.get8(0) & 0x80)) { + // DATA frame + uint8_t rand = 0x42; + for (uint32_t i=1; i> 1) ^ 0xB8; } + else { rand = (rand >> 1); } + } + } + + ToHex_P((unsigned char*)ezsp_buffer.getBuffer(), ezsp_buffer.len(), hex_char, sizeof(hex_char)); + Response_P(PSTR("{\"" D_JSON_ZIGBEE_EZSP_RECEIVED "\":\"%s\"}"), hex_char); + if (Settings.flag3.tuya_serial_mqtt_publish) { + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR)); + XdrvRulesProcess(); + } else { + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); // TODO move to LOG_LEVEL_DEBUG when stable + } + // now process the message + ZigbeeProcessInput(ezsp_buffer); + } + } else { + // the buffer timed-out, print error and discard + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": time-out, discarding %s, %d"), hex_char); + } + zigbee_buffer->setLen(0); // empty buffer + escape = false; + frame_complete = false; + } + +#endif // USE_ZIGBEE_EZSP + } /********************************************************************************************/ @@ -201,15 +342,20 @@ uint32_t strToUInt(const JsonVariant &val) { return 0; // couldn't parse anything } +#ifdef USE_ZIGBEE_ZNP // Do a factory reset of the CC2530 const unsigned char ZIGBEE_FACTORY_RESET[] PROGMEM = { Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_STARTUP_OPTION, 0x01 /* len */, 0x01 /* STARTOPT_CLEAR_CONFIG */}; //"2605030101"; // Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_STARTUP_OPTION, 0x01 len, 0x01 STARTOPT_CLEAR_CONFIG +#endif // USE_ZIGBEE_ZNP + void CmndZbReset(void) { if (ZigbeeSerial) { switch (XdrvMailbox.payload) { case 1: +#ifdef USE_ZIGBEE_ZNP ZigbeeZNPSend(ZIGBEE_FACTORY_RESET, sizeof(ZIGBEE_FACTORY_RESET)); +#endif // USE_ZIGBEE_ZNP eraseZigbeeDevices(); restart_flag = 2; ResponseCmndChar_P(PSTR(D_JSON_ZIGBEE_CC2530 " " D_JSON_RESET_AND_RESTARTING)); @@ -220,6 +366,38 @@ void CmndZbReset(void) { } } +#ifdef USE_ZIGBEE_ZNP + +void ZigbeeZNPSend(const uint8_t *msg, size_t len) { + if ((len < 2) || (len > 252)) { + // abort, message cannot be less than 2 bytes for CMD1 and CMD2 + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEEZNPSENT ": bad message len %d"), len); + return; + } + uint8_t data_len = len - 2; // removing CMD1 and CMD2 + + if (ZigbeeSerial) { + uint8_t fcs = data_len; + + ZigbeeSerial->write(ZIGBEE_SOF); // 0xFE + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend SOF %02X"), ZIGBEE_SOF); + ZigbeeSerial->write(data_len); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend LEN %02X"), data_len); + for (uint32_t i = 0; i < len; i++) { + uint8_t b = pgm_read_byte(msg + i); + ZigbeeSerial->write(b); + fcs ^= b; + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend byt %02X"), b); + } + ZigbeeSerial->write(fcs); // finally send fcs checksum byte + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend FCS %02X"), fcs); + } + // Now send a MQTT message to report the sent message + char hex_char[(len * 2) + 2]; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZNPSENT " %s"), + ToHex_P(msg, len, hex_char, sizeof(hex_char))); +} + // // Same code for `ZbZNPSend` and `ZbZNPReceive` // building the complete message (intro, length) @@ -264,36 +442,138 @@ void CmndZbZNPSend(void) CmndZbZNPSendOrReceive(true); } -void ZigbeeZNPSend(const uint8_t *msg, size_t len) { - if ((len < 2) || (len > 252)) { +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP + +// internal function to output a byte, and escape it (stuffing) if needed +void ZigbeeEZSPSend_Out(uint8_t out_byte) { + switch (out_byte) { + case 0x7E: // Flag byte + case 0x11: // XON + case 0x13: // XOFF + case 0x18: // Substitute byte + case 0x1A: // Cancel byte + case 0x7D: // Escape byte + ZigbeeSerial->write(ZIGBEE_EZSP_ESCAPE); // send Escape byte 0x7D + ZigbeeSerial->write(out_byte ^ 0x20); // send with bit 5 inverted + break; + default: + ZigbeeSerial->write(out_byte); // send unchanged + break; + } +} +// Send low-level EZSP frames +// +// The frame should contain the Control Byte and Data Field +// The frame shouldn't be escaped, nor randomized +// +// Before sending: +// - send Cancel byte (0x1A) if requested +// - randomize Data Field if DATA Frame +// - compute CRC16 +// - escape (stuff) reserved bytes +// - add EOF (0x7E) +// - send frame +// send_cancel: should we first send a EZSP_CANCEL (0x1A) before the message to clear any leftover +void ZigbeeEZSPSend(const uint8_t *msg, size_t len, bool send_cancel = false) { + if ((len < 1) || (len > 252)) { // abort, message cannot be less than 2 bytes for CMD1 and CMD2 - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEEZNPSENT ": bad message len %d"), len); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEE_EZSP_SENT ": bad message len %d"), len); return; } uint8_t data_len = len - 2; // removing CMD1 and CMD2 if (ZigbeeSerial) { - uint8_t fcs = data_len; + if (send_cancel) { + ZigbeeSerial->write(ZIGBEE_EZSP_CANCEL); // 0x1A + } - ZigbeeSerial->write(ZIGBEE_SOF); // 0xFE - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend SOF %02X"), ZIGBEE_SOF); - ZigbeeSerial->write(data_len); - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend LEN %02X"), data_len); - for (uint32_t i = 0; i < len; i++) { - uint8_t b = pgm_read_byte(msg + i); - ZigbeeSerial->write(b); - fcs ^= b; - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend byt %02X"), b); - } - ZigbeeSerial->write(fcs); // finally send fcs checksum byte - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend FCS %02X"), fcs); + bool data_frame = (0 == (msg[0] & 0x80)); + uint8_t rand = 0x42; // pseudo-randomizer initial value + uint16_t crc = 0xFFFF; // CRC16 CCITT initialization + + for (uint32_t i=0; i 0)) { + out_byte ^= rand; + if (rand & 1) { rand = (rand >> 1) ^ 0xB8; } + else { rand = (rand >> 1); } + } + + // compute CRC + crc = crc ^ ((uint16_t)out_byte << 8); + for (uint32_t i=0; i<8; i++) { + if (crc & 0x8000) { + crc = (crc << 1) ^ 0x1021; // polynom is x^16 + x^12 + x^5 + 1, CCITT standard + } else { + crc <<= 1; + } + } + + // output byte + ZigbeeEZSPSend_Out(out_byte); + } + // send CRC16 in big-endian + ZigbeeEZSPSend_Out(crc >> 8); + ZigbeeEZSPSend_Out(crc & 0xFF); + + // finally send End of Frame + ZigbeeSerial->write(ZIGBEE_EZSP_EOF); // 0x1A } // Now send a MQTT message to report the sent message char hex_char[(len * 2) + 2]; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZNPSENT " %s"), + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEE_EZSP_SENT " %s"), ToHex_P(msg, len, hex_char, sizeof(hex_char))); } +// +// Same code for `ZbZNPSend` and `ZbZNPReceive` +// building the complete message (intro, length) +// +void CmndZbEZSPSendOrReceive(bool send) +{ + if (ZigbeeSerial && (XdrvMailbox.data_len > 0)) { + uint8_t code; + + char *codes = RemoveSpace(XdrvMailbox.data); + int32_t size = strlen(XdrvMailbox.data); + + SBuffer buf((size+1)/2); + + while (size > 1) { + char stemp[3]; + strlcpy(stemp, codes, sizeof(stemp)); + code = strtol(stemp, nullptr, 16); + buf.add8(code); + size -= 2; + codes += 2; + } + if (send) { + // Command was `ZbEZSPSend` + ZigbeeEZSPSend(buf.getBuffer(), buf.len()); + } else { + // Command was `ZbEZSPReceive` + ZigbeeProcessInput(buf); + } + } + ResponseCmndDone(); +} + +// For debug purposes only, simulates a message received +void CmndZbEZSPReceive(void) +{ + CmndZbEZSPSendOrReceive(false); +} + +void CmndZbEZSPSend(void) +{ + CmndZbEZSPSendOrReceive(true); +} +#endif // USE_ZIGBEE_EZSP + // // Internal function, send the low-level frame // Input: @@ -311,6 +591,7 @@ void ZigbeeZNPSend(const uint8_t *msg, size_t len) { // void ZigbeeZCLSend_Raw(uint16_t shortaddr, uint16_t groupaddr, uint16_t clusterId, uint8_t endpoint, uint8_t cmdId, bool clusterSpecific, uint16_t manuf, const uint8_t *msg, size_t len, bool needResponse, uint8_t transacId) { +#ifdef USE_ZIGBEE_ZNP SBuffer buf(32+len); buf.add8(Z_SREQ | Z_AF); // 24 buf.add8(AF_DATA_REQUEST_EXT); // 02 @@ -342,6 +623,7 @@ void ZigbeeZCLSend_Raw(uint16_t shortaddr, uint16_t groupaddr, uint16_t clusterI } ZigbeeZNPSend(buf.getBuffer(), buf.len()); +#endif // USE_ZIGBEE_ZNP } /********************************************************************************************/ @@ -914,6 +1196,7 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind if (&to_group && dstLongAddr) { ResponseCmndChar_P(PSTR("Cannot have both \"ToDevice\" and \"ToGroup\"")); return; } if (!&to_group && !dstLongAddr) { ResponseCmndChar_P(PSTR("Missing \"ToDevice\" or \"ToGroup\"")); return; } +#ifdef USE_ZIGBEE_ZNP SBuffer buf(34); buf.add8(Z_SREQ | Z_ZDO); if (unbind) { @@ -935,6 +1218,7 @@ void ZbBindUnbind(bool unbind) { // false = bind, true = unbind } ZigbeeZNPSend(buf.getBuffer(), buf.len()); +#endif // USE_ZIGBEE_ZNP ResponseCmndDone(); } @@ -961,6 +1245,7 @@ void CmndZbBindState(void) { uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data); if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; } +#ifdef USE_ZIGBEE_ZNP SBuffer buf(10); buf.add8(Z_SREQ | Z_ZDO); // 25 buf.add8(ZDO_MGMT_BIND_REQ); // 33 @@ -968,6 +1253,7 @@ void CmndZbBindState(void) { buf.add8(0); // StartIndex = 0 ZigbeeZNPSend(buf.getBuffer(), buf.len()); +#endif // USE_ZIGBEE_ZNP ResponseCmndDone(); } @@ -1191,6 +1477,7 @@ void CmndZbPermitJoin(void) { duration = 0xFF; // unlimited time } +#ifdef USE_ZIGBEE_ZNP SBuffer buf(34); buf.add8(Z_SREQ | Z_ZDO); // 25 buf.add8(ZDO_MGMT_PERMIT_JOIN_REQ); // 36 @@ -1200,6 +1487,7 @@ void CmndZbPermitJoin(void) { buf.add8(0x00); // TCSignificance ZigbeeZNPSend(buf.getBuffer(), buf.len()); +#endif // USE_ZIGBEE_ZNP ResponseCmndDone(); } diff --git a/tasmota/xdrv_31_tasmota_client.ino b/tasmota/xdrv_31_tasmota_client.ino new file mode 100644 index 000000000..27e289373 --- /dev/null +++ b/tasmota/xdrv_31_tasmota_client.ino @@ -0,0 +1,585 @@ +/* + xdrv_31_tasmota_client.ino - Support for external microcontroller on serial + + Copyright (C) 2020 Andre Thomas and Theo Arends + + This program 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 3 of the License, or + (at your option) any later version. + + This program 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, see . +*/ + +#ifdef USE_TASMOTA_CLIENT +/*********************************************************************************************\ + * Tasmota to microcontroller +\*********************************************************************************************/ + +#define XDRV_31 31 + +#define CONST_STK_CRC_EOP 0x20 + +#define CMND_STK_GET_SYNC 0x30 +#define CMND_STK_SET_DEVICE 0x42 +#define CMND_STK_SET_DEVICE_EXT 0x45 +#define CMND_STK_ENTER_PROGMODE 0x50 +#define CMND_STK_LEAVE_PROGMODE 0x51 +#define CMND_STK_LOAD_ADDRESS 0x55 +#define CMND_STK_PROG_PAGE 0x64 + +/*************************************************\ + * Tasmota Client Specific Commands +\*************************************************/ + +#define CMND_START 0xFC +#define CMND_END 0xFD + +#define CMND_FEATURES 0x01 +#define CMND_JSON 0x02 +#define CMND_FUNC_EVERY_SECOND 0x03 +#define CMND_FUNC_EVERY_100_MSECOND 0x04 +#define CMND_CLIENT_SEND 0x05 +#define CMND_PUBLISH_TELE 0x06 +#define CMND_EXECUTE_CMND 0x07 + +#define PARAM_DATA_START 0xFE +#define PARAM_DATA_END 0xFF + +#include + +/* + * Embedding class in here since its rather specific to Arduino bootloader + */ + +class SimpleHexParse { + public: + SimpleHexParse(void); + uint8_t parseLine(char *hexline); + uint8_t ptr_l = 0; + uint8_t ptr_h = 0; + bool PageIsReady = false; + bool firstrun = true; + bool EndOfFile = false; + uint8_t FlashPage[128]; + uint8_t FlashPageIdx = 0; + uint8_t layoverBuffer[16]; + uint8_t layoverIdx = 0; + uint8_t getByte(char *hexline, uint8_t idx); +}; + +SimpleHexParse::SimpleHexParse(void) { + +} + +uint8_t SimpleHexParse::parseLine(char *hexline) { + if (layoverIdx) { + memcpy(&FlashPage[0], &layoverBuffer[0], layoverIdx); + FlashPageIdx = layoverIdx; + layoverIdx = 0; + } + uint8_t len = getByte(hexline, 1); + uint8_t addr_h = getByte(hexline, 2); + uint8_t addr_l = getByte(hexline, 3); + uint8_t rectype = getByte(hexline, 4); + for (uint8_t idx = 0; idx < len; idx++) { + if (FlashPageIdx < 128) { + FlashPage[FlashPageIdx] = getByte(hexline, idx+5); + FlashPageIdx++; + } else { // We have layover bytes + layoverBuffer[layoverIdx] = getByte(hexline, idx+5); + layoverIdx++; + } + } + if (1 == rectype) { + EndOfFile = true; + while (FlashPageIdx < 128) { + FlashPage[FlashPageIdx] = 0xFF; + FlashPageIdx++; + } + } + if (FlashPageIdx == 128) { + if (firstrun) { + firstrun = false; + } else { + ptr_l += 0x40; + if (ptr_l == 0) { + ptr_l = 0; + ptr_h++; + } + } + firstrun = false; + PageIsReady = true; + } + return 0; +} + +uint8_t SimpleHexParse::getByte(char* hexline, uint8_t idx) { + char buff[3]; + buff[3] = '\0'; + memcpy(&buff, &hexline[(idx*2)-1], 2); + return strtol(buff, 0, 16); +} + +/* + * End of embedded class SimpleHexParse + */ + +struct TCLIENT { + uint32_t spi_hex_size = 0; + uint32_t spi_sector_counter = 0; + uint8_t spi_sector_cursor = 0; + uint8_t inverted = LOW; + bool type = false; + bool flashing = false; + bool SerialEnabled = false; + uint8_t waitstate = 0; // We use this so that features detection does not slow down other stuff on startup + bool unsupported = false; +} TClient; + +typedef union { + uint32_t data; + struct { + uint32_t func_json_append : 1; // Client supports providing a JSON for TELEPERIOD + uint32_t func_every_second : 1; // Client supports receiving a FUNC_EVERY_SECOND callback with no response + uint32_t func_every_100_msecond : 1; // Client supports receiving a FUNC_EVERY_100_MSECOND callback with no response + uint32_t func_client_send : 1; // Client supports receiving commands with "client send xxx" + uint32_t spare4 : 1; + uint32_t spare5 : 1; + uint32_t spare6 : 1; + uint32_t spare7 : 1; + uint32_t spare8 : 1; + uint32_t spare9 : 1; + uint32_t spare10 : 1; + uint32_t spare11 : 1; + uint32_t spare12 : 1; + uint32_t spare13 : 1; + uint32_t spare14 : 1; + uint32_t spare15 : 1; + uint32_t spare16 : 1; + uint32_t spare17 : 1; + uint32_t spare18 : 1; + uint32_t spare19 : 1; + uint32_t spare20 : 1; + uint32_t spare21 : 1; + uint32_t spare22 : 1; + uint32_t spare23 : 1; + uint32_t spare24 : 1; + uint32_t spare25 : 1; + uint32_t spare26 : 1; + uint32_t spare27 : 1; + uint32_t spare28 : 1; + uint32_t spare29 : 1; + uint32_t spare30 : 1; + uint32_t spare31 : 1; + }; +} TClientFeatureCfg; + +/* + * The structure below must remain 4 byte aligned to be compatible with + * Tasmota as master + */ + +struct TCLIENT_FEATURES { + uint32_t features_version; + TClientFeatureCfg features; +} TClientSettings; + +struct TCLIENT_COMMAND { + uint8_t command; + uint8_t parameter; + uint8_t unused2; + uint8_t unused3; +} TClientCommand; + +TasmotaSerial *TasmotaClient_Serial; + +uint32_t TasmotaClient_FlashStart(void) { + return (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 2; // Stay on the safe side +} + +uint8_t TasmotaClient_UpdateInit(void) { + TClient.spi_hex_size = 0; + TClient.spi_sector_counter = TasmotaClient_FlashStart(); // Reset the pre-defined write address where firmware will temporarily be stored + TClient.spi_sector_cursor = 0; + return 0; +} + +void TasmotaClient_Reset(void) { + if (TClient.SerialEnabled) { + digitalWrite(Pin(GPIO_TASMOTACLIENT_RST), !TClient.inverted); + delay(1); + digitalWrite(Pin(GPIO_TASMOTACLIENT_RST), TClient.inverted); + delay(1); + digitalWrite(Pin(GPIO_TASMOTACLIENT_RST), !TClient.inverted); + delay(5); + } +} + +uint8_t TasmotaClient_waitForSerialData(int dataCount, int timeout) { + int timer = 0; + while (timer < timeout) { + if (TasmotaClient_Serial->available() >= dataCount) { + return 1; + } + delay(1); + timer++; + } + return 0; +} + +uint8_t TasmotaClient_sendBytes(uint8_t* bytes, int count) { + TasmotaClient_Serial->write(bytes, count); + TasmotaClient_waitForSerialData(2, 250); + uint8_t sync = TasmotaClient_Serial->read(); + uint8_t ok = TasmotaClient_Serial->read(); + if ((sync == 0x14) && (ok == 0x10)) { + return 1; + } + return 0; +} + +uint8_t TasmotaClient_execCmd(uint8_t cmd) { + uint8_t bytes[] = { cmd, CONST_STK_CRC_EOP }; + return TasmotaClient_sendBytes(bytes, 2); +} + +uint8_t TasmotaClient_execParam(uint8_t cmd, uint8_t* params, int count) { + uint8_t bytes[32]; + bytes[0] = cmd; + int i = 0; + while (i < count) { + bytes[i + 1] = params[i]; + i++; + } + bytes[i + 1] = CONST_STK_CRC_EOP; + return TasmotaClient_sendBytes(bytes, i + 2); +} + +uint8_t TasmotaClient_exitProgMode(void) { + return TasmotaClient_execCmd(CMND_STK_LEAVE_PROGMODE); // Exit programming mode +} + +uint8_t TasmotaClient_SetupFlash(void) { + uint8_t ProgParams[] = {0x86, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00}; + uint8_t ExtProgParams[] = {0x05, 0x04, 0xd7, 0xc2, 0x00}; + TasmotaClient_Serial->begin(USE_TASMOTA_CLIENT_FLASH_SPEED); + if (TasmotaClient_Serial->hardwareSerial()) { + ClaimSerial(); + } + + TasmotaClient_Reset(); + + uint8_t timeout = 0; + uint8_t no_error = 0; + while (50 > timeout) { + if (TasmotaClient_execCmd(CMND_STK_GET_SYNC)) { + timeout = 200; + no_error = 1; + } + timeout++; + delay(1); + } + if (no_error) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Found bootloader")); + } else { + no_error = 0; + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Bootloader could not be found")); + } + if (no_error) { + if (TasmotaClient_execParam(CMND_STK_SET_DEVICE, ProgParams, sizeof(ProgParams))) { + } else { + no_error = 0; + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Could not configure device for programming (1)")); + } + } + if (no_error) { + if (TasmotaClient_execParam(CMND_STK_SET_DEVICE_EXT, ExtProgParams, sizeof(ExtProgParams))) { + } else { + no_error = 0; + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Could not configure device for programming (2)")); + } + } + if (no_error) { + if (TasmotaClient_execCmd(CMND_STK_ENTER_PROGMODE)) { + } else { + no_error = 0; + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Failed to put bootloader into programming mode")); + } + } + return no_error; +} + +uint8_t TasmotaClient_loadAddress(uint8_t adrHi, uint8_t adrLo) { + uint8_t params[] = { adrLo, adrHi }; + return TasmotaClient_execParam(CMND_STK_LOAD_ADDRESS, params, sizeof(params)); +} + +void TasmotaClient_FlashPage(uint8_t addr_h, uint8_t addr_l, uint8_t* data) { + uint8_t Header[] = {CMND_STK_PROG_PAGE, 0x00, 0x80, 0x46}; + TasmotaClient_loadAddress(addr_h, addr_l); + TasmotaClient_Serial->write(Header, 4); + for (int i = 0; i < 128; i++) { + TasmotaClient_Serial->write(data[i]); + } + TasmotaClient_Serial->write(CONST_STK_CRC_EOP); + TasmotaClient_waitForSerialData(2, 250); + TasmotaClient_Serial->read(); + TasmotaClient_Serial->read(); +} + +void TasmotaClient_Flash(void) { + bool reading = true; + uint32_t read = 0; + uint32_t processed = 0; + char thishexline[50]; + uint8_t position = 0; + char* flash_buffer; + + SimpleHexParse hexParse = SimpleHexParse(); + + if (!TasmotaClient_SetupFlash()) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Flashing aborted!")); + TClient.flashing = false; + restart_flag = 2; + return; + } + + flash_buffer = new char[SPI_FLASH_SEC_SIZE]; + uint32_t flash_start = TasmotaClient_FlashStart() * SPI_FLASH_SEC_SIZE; + while (reading) { + ESP.flashRead(flash_start + read, (uint32_t*)flash_buffer, SPI_FLASH_SEC_SIZE); + read = read + SPI_FLASH_SEC_SIZE; + if (read >= TClient.spi_hex_size) { + reading = false; + } + for (uint32_t ca = 0; ca < SPI_FLASH_SEC_SIZE; ca++) { + processed++; + if ((processed <= TClient.spi_hex_size) && (!hexParse.EndOfFile)) { + if (':' == flash_buffer[ca]) { + position = 0; + } + if (0x0D == flash_buffer[ca]) { + thishexline[position] = 0; + hexParse.parseLine(thishexline); + if (hexParse.PageIsReady) { + TasmotaClient_FlashPage(hexParse.ptr_h, hexParse.ptr_l, hexParse.FlashPage); + hexParse.PageIsReady = false; + hexParse.FlashPageIdx = 0; + } + } else { + if (0x0A != flash_buffer[ca]) { + thishexline[position] = flash_buffer[ca]; + position++; + } + } + } + } + } + TasmotaClient_exitProgMode(); + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Flash done!")); + TClient.flashing = false; + restart_flag = 2; +} + +void TasmotaClient_SetFlagFlashing(bool value) { + TClient.flashing = value; +} + +bool TasmotaClient_GetFlagFlashing(void) { + return TClient.flashing; +} + +void TasmotaClient_WriteBuffer(uint8_t *buf, size_t size) { + if (0 == TClient.spi_sector_cursor) { // Starting a new sector write so we need to erase it first + ESP.flashEraseSector(TClient.spi_sector_counter); + } + TClient.spi_sector_cursor++; + ESP.flashWrite((TClient.spi_sector_counter * SPI_FLASH_SEC_SIZE) + ((TClient.spi_sector_cursor-1)*2048), (uint32_t*)buf, size); + TClient.spi_hex_size = TClient.spi_hex_size + size; + if (2 == TClient.spi_sector_cursor) { // The web upload sends 2048 bytes at a time so keep track of the cursor position to reset it for the next flash sector erase + TClient.spi_sector_cursor = 0; + TClient.spi_sector_counter++; + } +} + +void TasmotaClient_Init(void) { + if (TClient.type) { + return; + } + if (10 > TClient.waitstate) { + TClient.waitstate++; + return; + } + if (!TClient.SerialEnabled) { + if (PinUsed(GPIO_TASMOTACLIENT_RXD) && PinUsed(GPIO_TASMOTACLIENT_TXD) && + (PinUsed(GPIO_TASMOTACLIENT_RST) || PinUsed(GPIO_TASMOTACLIENT_RST_INV))) { + TasmotaClient_Serial = new TasmotaSerial(Pin(GPIO_TASMOTACLIENT_RXD), Pin(GPIO_TASMOTACLIENT_TXD), 1, 0, 200); + if (TasmotaClient_Serial->begin(USE_TASMOTA_CLIENT_SERIAL_SPEED)) { + if (TasmotaClient_Serial->hardwareSerial()) { + ClaimSerial(); + } + TasmotaClient_Serial->setTimeout(100); // Theo 20200502 - increase from 50 + if (PinUsed(GPIO_TASMOTACLIENT_RST_INV)) { + SetPin(Pin(GPIO_TASMOTACLIENT_RST_INV), GPIO_TASMOTACLIENT_RST); + TClient.inverted = HIGH; + } + pinMode(Pin(GPIO_TASMOTACLIENT_RST), OUTPUT); + TClient.SerialEnabled = true; + TasmotaClient_Reset(); + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Enabled")); + } + } + } + if (TClient.SerialEnabled) { // All go for hardware now we need to detect features if there are any + TasmotaClient_sendCmnd(CMND_FEATURES, 0); + char buffer[32] = { 0 }; + TasmotaClient_Serial->readBytesUntil(char(PARAM_DATA_START), buffer, sizeof(buffer)); + uint8_t len = TasmotaClient_Serial->readBytesUntil(char(PARAM_DATA_END), buffer, sizeof(buffer)); + + if (len) { AddLogBuffer(LOG_LEVEL_DEBUG_MORE, (uint8_t*)buffer, len); } // Theo 20200502 - DMP: 99 17 34 01 02 00 00 00 + + memcpy(&TClientSettings, &buffer, sizeof(TClientSettings)); + if (20191129 == TClientSettings.features_version) { + TClient.type = true; + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Version %u"), TClientSettings.features_version); + } else { + if ((!TClient.unsupported) && (TClientSettings.features_version > 0)) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Version %u not supported!"), TClientSettings.features_version); + TClient.unsupported = true; + } + } + } +} + +void TasmotaClient_Show(void) { + if ((TClient.type) && (TClientSettings.features.func_json_append)) { + char buffer[100]; + TasmotaClient_sendCmnd(CMND_JSON, 0); + TasmotaClient_Serial->readBytesUntil(char(PARAM_DATA_START), buffer, sizeof(buffer)-1); + uint8_t len = TasmotaClient_Serial->readBytesUntil(char(PARAM_DATA_END), buffer, sizeof(buffer)-1); + buffer[len] = '\0'; + ResponseAppend_P(PSTR(",\"TasmotaClient\":%s"), buffer); + } +} + +void TasmotaClient_sendCmnd(uint8_t cmnd, uint8_t param) { + TClientCommand.command = cmnd; + TClientCommand.parameter = param; + char buffer[sizeof(TClientCommand)+2]; + buffer[0] = CMND_START; + memcpy(&buffer[1], &TClientCommand, sizeof(TClientCommand)); + buffer[sizeof(TClientCommand)+1] = CMND_END; + + TasmotaClient_Serial->flush(); // Theo 20200502 + + for (uint8_t ca = 0; ca < sizeof(buffer); ca++) { + TasmotaClient_Serial->write(buffer[ca]); + } +} + +#define D_PRFX_CLIENT "Client" +#define D_CMND_CLIENT_RESET "Reset" +#define D_CMND_CLIENT_SEND "Send" + +const char kTasmotaClientCommands[] PROGMEM = D_PRFX_CLIENT "|" + D_CMND_CLIENT_RESET "|" D_CMND_CLIENT_SEND; + +void (* const TasmotaClientCommand[])(void) PROGMEM = { + &CmndClientReset, &CmndClientSend }; + +void CmndClientReset(void) { + TasmotaClient_Reset(); + TClient.type = false; // Force redetection + TClient.waitstate = 7; // give it at least 3 seconds to restart from bootloader + TClient.unsupported = false; // Reset unsupported flag + ResponseCmndDone(); +} + +void CmndClientSend(void) { + if (0 < XdrvMailbox.data_len) { + TasmotaClient_sendCmnd(CMND_CLIENT_SEND, XdrvMailbox.data_len); + TasmotaClient_Serial->write(char(PARAM_DATA_START)); + for (uint8_t idx = 0; idx < XdrvMailbox.data_len; idx++) { + TasmotaClient_Serial->write(XdrvMailbox.data[idx]); + } + TasmotaClient_Serial->write(char(PARAM_DATA_END)); + } + ResponseCmndDone(); +} + +void TasmotaClient_ProcessIn(void) { + uint8_t cmnd = TasmotaClient_Serial->read(); + if (CMND_START == cmnd) { + TasmotaClient_waitForSerialData(sizeof(TClientCommand),50); + uint8_t buffer[sizeof(TClientCommand)]; + for (uint8_t idx = 0; idx < sizeof(TClientCommand); idx++) { + buffer[idx] = TasmotaClient_Serial->read(); + } + TasmotaClient_Serial->read(); // read trailing byte of command + memcpy(&TClientCommand, &buffer, sizeof(TClientCommand)); + char inbuf[TClientCommand.parameter+1]; + TasmotaClient_waitForSerialData(TClientCommand.parameter, 50); + TasmotaClient_Serial->read(); // Read leading byte + for (uint8_t idx = 0; idx < TClientCommand.parameter; idx++) { + inbuf[idx] = TasmotaClient_Serial->read(); + } + TasmotaClient_Serial->read(); // Read trailing byte + inbuf[TClientCommand.parameter] = '\0'; + + if (CMND_PUBLISH_TELE == TClientCommand.command) { // We need to publish stat/ with incoming stream as content + Response_P(PSTR("{\"TasmotaClient\":")); + ResponseAppend_P("%s", inbuf); + ResponseJsonEnd(); + MqttPublishPrefixTopic_P(RESULT_OR_TELE, mqtt_data); + XdrvRulesProcess(); + } + if (CMND_EXECUTE_CMND == TClientCommand.command) { // We need to execute the incoming command + ExecuteCommand(inbuf, SRC_IGNORE); + } + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv31(uint8_t function) { + bool result = false; + + switch (function) { + case FUNC_EVERY_100_MSECOND: + if (TClient.type) { + if (TasmotaClient_Serial->available()) { + TasmotaClient_ProcessIn(); + } + if (TClientSettings.features.func_every_100_msecond) { + TasmotaClient_sendCmnd(CMND_FUNC_EVERY_100_MSECOND, 0); + } + } + break; + case FUNC_EVERY_SECOND: + if ((TClient.type) && (TClientSettings.features.func_every_second)) { + TasmotaClient_sendCmnd(CMND_FUNC_EVERY_SECOND, 0); + } + TasmotaClient_Init(); + break; + case FUNC_JSON_APPEND: + if ((TClient.type) && (TClientSettings.features.func_json_append)) { + TasmotaClient_Show(); + } + break; + case FUNC_COMMAND: + result = DecodeCommand(kTasmotaClientCommands, TasmotaClientCommand); + break; + } + return result; +} + +#endif // USE_TASMOTA_CLIENT diff --git a/tasmota/xdrv_31_tasmota_slave.ino b/tasmota/xdrv_31_tasmota_slave.ino deleted file mode 100644 index 38306a791..000000000 --- a/tasmota/xdrv_31_tasmota_slave.ino +++ /dev/null @@ -1,615 +0,0 @@ -/* - xdrv_31_tasmota_slave.ino - Support for external microcontroller slave on serial - - Copyright (C) 2020 Andre Thomas and Theo Arends - - This program 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 3 of the License, or - (at your option) any later version. - - This program 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, see . -*/ - -#ifdef USE_TASMOTA_SLAVE -/*********************************************************************************************\ - * Tasmota slave -\*********************************************************************************************/ - -#define XDRV_31 31 - -#define CONST_STK_CRC_EOP 0x20 - -#define CMND_STK_GET_SYNC 0x30 -#define CMND_STK_SET_DEVICE 0x42 -#define CMND_STK_SET_DEVICE_EXT 0x45 -#define CMND_STK_ENTER_PROGMODE 0x50 -#define CMND_STK_LEAVE_PROGMODE 0x51 -#define CMND_STK_LOAD_ADDRESS 0x55 -#define CMND_STK_PROG_PAGE 0x64 - -/*************************************************\ - * Tasmota Slave Specific Commands -\*************************************************/ - -#define CMND_START 0xFC -#define CMND_END 0xFD - -#define CMND_FEATURES 0x01 -#define CMND_JSON 0x02 -#define CMND_FUNC_EVERY_SECOND 0x03 -#define CMND_FUNC_EVERY_100_MSECOND 0x04 -#define CMND_SLAVE_SEND 0x05 -#define CMND_PUBLISH_TELE 0x06 -#define CMND_EXECUTE_CMND 0x07 - -#define PARAM_DATA_START 0xFE -#define PARAM_DATA_END 0xFF - -#include - -/* - * Embedding class in here since its rather specific to Arduino bootloader - */ - -class SimpleHexParse { - public: - SimpleHexParse(void); - uint8_t parseLine(char *hexline); - uint8_t ptr_l = 0; - uint8_t ptr_h = 0; - bool PageIsReady = false; - bool firstrun = true; - bool EndOfFile = false; - uint8_t FlashPage[128]; - uint8_t FlashPageIdx = 0; - uint8_t layoverBuffer[16]; - uint8_t layoverIdx = 0; - uint8_t getByte(char *hexline, uint8_t idx); -}; - -SimpleHexParse::SimpleHexParse(void) -{ - -} - -uint8_t SimpleHexParse::parseLine(char *hexline) -{ - if (layoverIdx) { - memcpy(&FlashPage[0], &layoverBuffer[0], layoverIdx); - FlashPageIdx = layoverIdx; - layoverIdx = 0; - } - uint8_t len = getByte(hexline, 1); - uint8_t addr_h = getByte(hexline, 2); - uint8_t addr_l = getByte(hexline, 3); - uint8_t rectype = getByte(hexline, 4); - for (uint8_t idx = 0; idx < len; idx++) { - if (FlashPageIdx < 128) { - FlashPage[FlashPageIdx] = getByte(hexline, idx+5); - FlashPageIdx++; - } else { // We have layover bytes - layoverBuffer[layoverIdx] = getByte(hexline, idx+5); - layoverIdx++; - } - } - if (1 == rectype) { - EndOfFile = true; - while (FlashPageIdx < 128) { - FlashPage[FlashPageIdx] = 0xFF; - FlashPageIdx++; - } - } - if (FlashPageIdx == 128) { - if (firstrun) { - firstrun = false; - } else { - ptr_l += 0x40; - if (ptr_l == 0) { - ptr_l = 0; - ptr_h++; - } - } - firstrun = false; - PageIsReady = true; - } - return 0; -} - -uint8_t SimpleHexParse::getByte(char* hexline, uint8_t idx) -{ - char buff[3]; - buff[3] = '\0'; - memcpy(&buff, &hexline[(idx*2)-1], 2); - return strtol(buff, 0, 16); -} - -/* - * End of embedded class SimpleHexParse - */ - -struct TSLAVE { - uint32_t spi_hex_size = 0; - uint32_t spi_sector_counter = 0; - uint8_t spi_sector_cursor = 0; - uint8_t inverted = LOW; - bool type = false; - bool flashing = false; - bool SerialEnabled = false; - uint8_t waitstate = 0; // We use this so that features detection does not slow down other stuff on startup - bool unsupported = false; -} TSlave; - -typedef union { - uint32_t data; - struct { - uint32_t func_json_append : 1; // Slave supports providing a JSON for TELEPERIOD - uint32_t func_every_second : 1; // Slave supports receiving a FUNC_EVERY_SECOND callback with no response - uint32_t func_every_100_msecond : 1; // Slave supports receiving a FUNC_EVERY_100_MSECOND callback with no response - uint32_t func_slave_send : 1; // Slave supports receiving commands with "slave send xxx" - uint32_t spare4 : 1; - uint32_t spare5 : 1; - uint32_t spare6 : 1; - uint32_t spare7 : 1; - uint32_t spare8 : 1; - uint32_t spare9 : 1; - uint32_t spare10 : 1; - uint32_t spare11 : 1; - uint32_t spare12 : 1; - uint32_t spare13 : 1; - uint32_t spare14 : 1; - uint32_t spare15 : 1; - uint32_t spare16 : 1; - uint32_t spare17 : 1; - uint32_t spare18 : 1; - uint32_t spare19 : 1; - uint32_t spare20 : 1; - uint32_t spare21 : 1; - uint32_t spare22 : 1; - uint32_t spare23 : 1; - uint32_t spare24 : 1; - uint32_t spare25 : 1; - uint32_t spare26 : 1; - uint32_t spare27 : 1; - uint32_t spare28 : 1; - uint32_t spare29 : 1; - uint32_t spare30 : 1; - uint32_t spare31 : 1; - }; -} TSlaveFeatureCfg; - -/* - * The structure below must remain 4 byte aligned to be compatible with - * Tasmota as master - */ - -struct TSLAVE_FEATURES { - uint32_t features_version; - TSlaveFeatureCfg features; -} TSlaveSettings; - -struct TSLAVE_COMMAND { - uint8_t command; - uint8_t parameter; - uint8_t unused2; - uint8_t unused3; -} TSlaveCommand; - -TasmotaSerial *TasmotaSlave_Serial; - -uint32_t TasmotaSlave_FlashStart(void) -{ - return (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 2; // Stay on the safe side -} - -uint8_t TasmotaSlave_UpdateInit(void) -{ - TSlave.spi_hex_size = 0; - TSlave.spi_sector_counter = TasmotaSlave_FlashStart(); // Reset the pre-defined write address where firmware will temporarily be stored - TSlave.spi_sector_cursor = 0; - return 0; -} - -void TasmotaSlave_Reset(void) -{ - if (TSlave.SerialEnabled) { - digitalWrite(Pin(GPIO_TASMOTASLAVE_RST), !TSlave.inverted); - delay(1); - digitalWrite(Pin(GPIO_TASMOTASLAVE_RST), TSlave.inverted); - delay(1); - digitalWrite(Pin(GPIO_TASMOTASLAVE_RST), !TSlave.inverted); - delay(5); - } -} - -uint8_t TasmotaSlave_waitForSerialData(int dataCount, int timeout) -{ - int timer = 0; - while (timer < timeout) { - if (TasmotaSlave_Serial->available() >= dataCount) { - return 1; - } - delay(1); - timer++; - } - return 0; -} - -uint8_t TasmotaSlave_sendBytes(uint8_t* bytes, int count) -{ - TasmotaSlave_Serial->write(bytes, count); - TasmotaSlave_waitForSerialData(2, 250); - uint8_t sync = TasmotaSlave_Serial->read(); - uint8_t ok = TasmotaSlave_Serial->read(); - if ((sync == 0x14) && (ok == 0x10)) { - return 1; - } - return 0; -} - -uint8_t TasmotaSlave_execCmd(uint8_t cmd) -{ - uint8_t bytes[] = { cmd, CONST_STK_CRC_EOP }; - return TasmotaSlave_sendBytes(bytes, 2); -} - -uint8_t TasmotaSlave_execParam(uint8_t cmd, uint8_t* params, int count) -{ - uint8_t bytes[32]; - bytes[0] = cmd; - int i = 0; - while (i < count) { - bytes[i + 1] = params[i]; - i++; - } - bytes[i + 1] = CONST_STK_CRC_EOP; - return TasmotaSlave_sendBytes(bytes, i + 2); -} - -uint8_t TasmotaSlave_exitProgMode(void) -{ - return TasmotaSlave_execCmd(CMND_STK_LEAVE_PROGMODE); // Exit programming mode -} - -uint8_t TasmotaSlave_SetupFlash(void) -{ - uint8_t ProgParams[] = {0x86, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00}; - uint8_t ExtProgParams[] = {0x05, 0x04, 0xd7, 0xc2, 0x00}; - TasmotaSlave_Serial->begin(USE_TASMOTA_SLAVE_FLASH_SPEED); - if (TasmotaSlave_Serial->hardwareSerial()) { - ClaimSerial(); - } - - TasmotaSlave_Reset(); - - uint8_t timeout = 0; - uint8_t no_error = 0; - while (50 > timeout) { - if (TasmotaSlave_execCmd(CMND_STK_GET_SYNC)) { - timeout = 200; - no_error = 1; - } - timeout++; - delay(1); - } - if (no_error) { - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Found bootloader")); - } else { - no_error = 0; - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Bootloader could not be found")); - } - if (no_error) { - if (TasmotaSlave_execParam(CMND_STK_SET_DEVICE, ProgParams, sizeof(ProgParams))) { - } else { - no_error = 0; - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Could not configure device for programming (1)")); - } - } - if (no_error) { - if (TasmotaSlave_execParam(CMND_STK_SET_DEVICE_EXT, ExtProgParams, sizeof(ExtProgParams))) { - } else { - no_error = 0; - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Could not configure device for programming (2)")); - } - } - if (no_error) { - if (TasmotaSlave_execCmd(CMND_STK_ENTER_PROGMODE)) { - } else { - no_error = 0; - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Failed to put bootloader into programming mode")); - } - } - return no_error; -} - -uint8_t TasmotaSlave_loadAddress(uint8_t adrHi, uint8_t adrLo) -{ - uint8_t params[] = { adrLo, adrHi }; - return TasmotaSlave_execParam(CMND_STK_LOAD_ADDRESS, params, sizeof(params)); -} - -void TasmotaSlave_FlashPage(uint8_t addr_h, uint8_t addr_l, uint8_t* data) -{ - uint8_t Header[] = {CMND_STK_PROG_PAGE, 0x00, 0x80, 0x46}; - TasmotaSlave_loadAddress(addr_h, addr_l); - TasmotaSlave_Serial->write(Header, 4); - for (int i = 0; i < 128; i++) { - TasmotaSlave_Serial->write(data[i]); - } - TasmotaSlave_Serial->write(CONST_STK_CRC_EOP); - TasmotaSlave_waitForSerialData(2, 250); - TasmotaSlave_Serial->read(); - TasmotaSlave_Serial->read(); -} - -void TasmotaSlave_Flash(void) -{ - bool reading = true; - uint32_t read = 0; - uint32_t processed = 0; - char thishexline[50]; - uint8_t position = 0; - char* flash_buffer; - - SimpleHexParse hexParse = SimpleHexParse(); - - if (!TasmotaSlave_SetupFlash()) { - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Flashing aborted!")); - TSlave.flashing = false; - restart_flag = 2; - return; - } - - flash_buffer = new char[SPI_FLASH_SEC_SIZE]; - uint32_t flash_start = TasmotaSlave_FlashStart() * SPI_FLASH_SEC_SIZE; - while (reading) { - ESP.flashRead(flash_start + read, (uint32_t*)flash_buffer, SPI_FLASH_SEC_SIZE); - read = read + SPI_FLASH_SEC_SIZE; - if (read >= TSlave.spi_hex_size) { - reading = false; - } - for (uint32_t ca = 0; ca < SPI_FLASH_SEC_SIZE; ca++) { - processed++; - if ((processed <= TSlave.spi_hex_size) && (!hexParse.EndOfFile)) { - if (':' == flash_buffer[ca]) { - position = 0; - } - if (0x0D == flash_buffer[ca]) { - thishexline[position] = 0; - hexParse.parseLine(thishexline); - if (hexParse.PageIsReady) { - TasmotaSlave_FlashPage(hexParse.ptr_h, hexParse.ptr_l, hexParse.FlashPage); - hexParse.PageIsReady = false; - hexParse.FlashPageIdx = 0; - } - } else { - if (0x0A != flash_buffer[ca]) { - thishexline[position] = flash_buffer[ca]; - position++; - } - } - } - } - } - TasmotaSlave_exitProgMode(); - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Flash done!")); - TSlave.flashing = false; - restart_flag = 2; -} - -void TasmotaSlave_SetFlagFlashing(bool value) -{ - TSlave.flashing = value; -} - -bool TasmotaSlave_GetFlagFlashing(void) -{ - return TSlave.flashing; -} - -void TasmotaSlave_WriteBuffer(uint8_t *buf, size_t size) -{ - if (0 == TSlave.spi_sector_cursor) { // Starting a new sector write so we need to erase it first - ESP.flashEraseSector(TSlave.spi_sector_counter); - } - TSlave.spi_sector_cursor++; - ESP.flashWrite((TSlave.spi_sector_counter * SPI_FLASH_SEC_SIZE) + ((TSlave.spi_sector_cursor-1)*2048), (uint32_t*)buf, size); - TSlave.spi_hex_size = TSlave.spi_hex_size + size; - if (2 == TSlave.spi_sector_cursor) { // The web upload sends 2048 bytes at a time so keep track of the cursor position to reset it for the next flash sector erase - TSlave.spi_sector_cursor = 0; - TSlave.spi_sector_counter++; - } -} - -void TasmotaSlave_Init(void) -{ - if (TSlave.type) { - return; - } - if (10 > TSlave.waitstate) { - TSlave.waitstate++; - return; - } - if (!TSlave.SerialEnabled) { - if (PinUsed(GPIO_TASMOTASLAVE_RXD) && PinUsed(GPIO_TASMOTASLAVE_TXD) && - (PinUsed(GPIO_TASMOTASLAVE_RST) || PinUsed(GPIO_TASMOTASLAVE_RST_INV))) { - TasmotaSlave_Serial = new TasmotaSerial(Pin(GPIO_TASMOTASLAVE_RXD), Pin(GPIO_TASMOTASLAVE_TXD), 1, 0, 200); - if (TasmotaSlave_Serial->begin(USE_TASMOTA_SLAVE_SERIAL_SPEED)) { - if (TasmotaSlave_Serial->hardwareSerial()) { - ClaimSerial(); - } - TasmotaSlave_Serial->setTimeout(100); // Theo 20200502 - increase from 50 - if (PinUsed(GPIO_TASMOTASLAVE_RST_INV)) { - SetPin(Pin(GPIO_TASMOTASLAVE_RST_INV), GPIO_TASMOTASLAVE_RST); - TSlave.inverted = HIGH; - } - pinMode(Pin(GPIO_TASMOTASLAVE_RST), OUTPUT); - TSlave.SerialEnabled = true; - TasmotaSlave_Reset(); - AddLog_P2(LOG_LEVEL_INFO, PSTR("Tasmota Slave Enabled")); - } - } - } - if (TSlave.SerialEnabled) { // All go for hardware now we need to detect features if there are any - TasmotaSlave_sendCmnd(CMND_FEATURES, 0); - char buffer[32] = { 0 }; - TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_START), buffer, sizeof(buffer)); - uint8_t len = TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_END), buffer, sizeof(buffer)); - - if (len) { AddLogBuffer(LOG_LEVEL_DEBUG_MORE, (uint8_t*)buffer, len); } // Theo 20200502 - DMP: 99 17 34 01 02 00 00 00 - - memcpy(&TSlaveSettings, &buffer, sizeof(TSlaveSettings)); - if (20191129 == TSlaveSettings.features_version) { - TSlave.type = true; - AddLog_P2(LOG_LEVEL_INFO, PSTR("Tasmota Slave Version %u"), TSlaveSettings.features_version); - } else { - if ((!TSlave.unsupported) && (TSlaveSettings.features_version > 0)) { - AddLog_P2(LOG_LEVEL_INFO, PSTR("Tasmota Slave Version %u not supported!"), TSlaveSettings.features_version); - TSlave.unsupported = true; - } - } - } -} - -void TasmotaSlave_Show(void) -{ - if ((TSlave.type) && (TSlaveSettings.features.func_json_append)) { - char buffer[100]; - TasmotaSlave_sendCmnd(CMND_JSON, 0); - TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_START), buffer, sizeof(buffer)-1); - uint8_t len = TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_END), buffer, sizeof(buffer)-1); - buffer[len] = '\0'; - ResponseAppend_P(PSTR(",\"TasmotaSlave\":%s"), buffer); - } -} - -void TasmotaSlave_sendCmnd(uint8_t cmnd, uint8_t param) -{ - TSlaveCommand.command = cmnd; - TSlaveCommand.parameter = param; - char buffer[sizeof(TSlaveCommand)+2]; - buffer[0] = CMND_START; - memcpy(&buffer[1], &TSlaveCommand, sizeof(TSlaveCommand)); - buffer[sizeof(TSlaveCommand)+1] = CMND_END; - - TasmotaSlave_Serial->flush(); // Theo 20200502 - - for (uint8_t ca = 0; ca < sizeof(buffer); ca++) { - TasmotaSlave_Serial->write(buffer[ca]); - } -} - -#define D_PRFX_SLAVE "Slave" -#define D_CMND_SLAVE_RESET "Reset" -#define D_CMND_SLAVE_SEND "Send" - -const char kTasmotaSlaveCommands[] PROGMEM = D_PRFX_SLAVE "|" - D_CMND_SLAVE_RESET "|" D_CMND_SLAVE_SEND; - -void (* const TasmotaSlaveCommand[])(void) PROGMEM = { - &CmndTasmotaSlaveReset, &CmndTasmotaSlaveSend }; - -void CmndTasmotaSlaveReset(void) -{ - TasmotaSlave_Reset(); - TSlave.type = false; // Force redetection - TSlave.waitstate = 7; // give it at least 3 seconds to restart from bootloader - TSlave.unsupported = false; // Reset unsupported flag - ResponseCmndDone(); -} - -void CmndTasmotaSlaveSend(void) -{ - if (0 < XdrvMailbox.data_len) { - TasmotaSlave_sendCmnd(CMND_SLAVE_SEND, XdrvMailbox.data_len); - TasmotaSlave_Serial->write(char(PARAM_DATA_START)); - for (uint8_t idx = 0; idx < XdrvMailbox.data_len; idx++) { - TasmotaSlave_Serial->write(XdrvMailbox.data[idx]); - } - TasmotaSlave_Serial->write(char(PARAM_DATA_END)); - } - ResponseCmndDone(); -} - -void TasmotaSlave_ProcessIn(void) -{ - uint8_t cmnd = TasmotaSlave_Serial->read(); - switch (cmnd) { - case CMND_START: - TasmotaSlave_waitForSerialData(sizeof(TSlaveCommand),50); - uint8_t buffer[sizeof(TSlaveCommand)]; - for (uint8_t idx = 0; idx < sizeof(TSlaveCommand); idx++) { - buffer[idx] = TasmotaSlave_Serial->read(); - } - TasmotaSlave_Serial->read(); // read trailing byte of command - memcpy(&TSlaveCommand, &buffer, sizeof(TSlaveCommand)); - char inbuf[TSlaveCommand.parameter+1]; - TasmotaSlave_waitForSerialData(TSlaveCommand.parameter, 50); - TasmotaSlave_Serial->read(); // Read leading byte - for (uint8_t idx = 0; idx < TSlaveCommand.parameter; idx++) { - inbuf[idx] = TasmotaSlave_Serial->read(); - } - TasmotaSlave_Serial->read(); // Read trailing byte - inbuf[TSlaveCommand.parameter] = '\0'; - - if (CMND_PUBLISH_TELE == TSlaveCommand.command) { // We need to publish stat/ with incoming stream as content - Response_P(PSTR("{\"TasmotaSlave\":")); - ResponseAppend_P("%s", inbuf); - ResponseJsonEnd(); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, mqtt_data); - XdrvRulesProcess(); - } - if (CMND_EXECUTE_CMND == TSlaveCommand.command) { // We need to execute the incoming command - ExecuteCommand(inbuf, SRC_IGNORE); - } - break; - default: - break; - } -} - - -/*********************************************************************************************\ - * Interface -\*********************************************************************************************/ - -bool Xdrv31(uint8_t function) -{ - bool result = false; - - switch (function) { - case FUNC_EVERY_100_MSECOND: - if (TSlave.type) { - if (TasmotaSlave_Serial->available()) { - TasmotaSlave_ProcessIn(); - } - if (TSlaveSettings.features.func_every_100_msecond) { - TasmotaSlave_sendCmnd(CMND_FUNC_EVERY_100_MSECOND, 0); - } - } - break; - case FUNC_EVERY_SECOND: - if ((TSlave.type) && (TSlaveSettings.features.func_every_second)) { - TasmotaSlave_sendCmnd(CMND_FUNC_EVERY_SECOND, 0); - } - TasmotaSlave_Init(); - break; - case FUNC_JSON_APPEND: - if ((TSlave.type) && (TSlaveSettings.features.func_json_append)) { - TasmotaSlave_Show(); - } - break; - case FUNC_COMMAND: - result = DecodeCommand(kTasmotaSlaveCommands, TasmotaSlaveCommand); - break; - } - return result; -} - -#endif // USE_TASMOTA_SLAVE diff --git a/tasmota/xdrv_40_telegram.ino b/tasmota/xdrv_40_telegram.ino index 97c5aa453..a7beb5005 100644 --- a/tasmota/xdrv_40_telegram.ino +++ b/tasmota/xdrv_40_telegram.ino @@ -322,7 +322,7 @@ String TelegramExecuteCommand(const char *svalue) { } void TelegramLoop(void) { - if (!global_state.wifi_down && (Telegram.recv_enable || Telegram.echo_enable)) { + if (!global_state.network_down && (Telegram.recv_enable || Telegram.echo_enable)) { switch (Telegram.state) { case 0: TelegramInit(); diff --git a/tasmota/xdrv_81_webcam.ino b/tasmota/xdrv_81_webcam.ino index 9cbeb4133..b0dab47b7 100644 --- a/tasmota/xdrv_81_webcam.ino +++ b/tasmota/xdrv_81_webcam.ino @@ -23,7 +23,7 @@ * ESP32 webcam based on example in Arduino-ESP32 library * * Template as used on ESP32-CAM WiFi + bluetooth Camera Module Development Board ESP32 With Camera Module OV2640 Geekcreit for Arduino - * {"NAME":"AITHINKER CAM No SPI","GPIO":[4992,65504,65504,65504,65504,5088,65504,65504,65504,65504,65504,65504,65504,65504,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,65504,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1} + * {"NAME":"AITHINKER CAM","GPIO":[4992,1,1,1,1,5088,1,1,1,1,1,1,1,1,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,1,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1} * * Supported commands: * WcStream = Control streaming, 0 = stop, 1 = start @@ -792,7 +792,7 @@ void HandleWebcamRoot(void) { /*********************************************************************************************/ uint32_t WcSetStreamserver(uint32_t flag) { - if (global_state.wifi_down) { return 0; } + if (global_state.network_down) { return 0; } Wc.stream_active = 0; diff --git a/tasmota/xdrv_82_ethernet.ino b/tasmota/xdrv_82_ethernet.ino index e20cde4e5..cccac57b7 100644 --- a/tasmota/xdrv_82_ethernet.ino +++ b/tasmota/xdrv_82_ethernet.ino @@ -31,7 +31,8 @@ * GPIO26 - EMAC_RXD1(RMII) * GPIO27 - EMAC_RX_CRS_DV * - * {"NAME":"Olimex ESP32-PoE","GPIO":[65504,65504,65504,65504,65504,65504,0,0,5536,65504,65504,65504,65504,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,65504,65504,65504,65504,65504,0,0,65504],"FLAG":0,"BASE":1} + * {"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} + * {"NAME":"wESP32","GPIO":[1,1,1,1,1,1,0,0,0,1,1,1,5568,5600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} * \*********************************************************************************************/ @@ -49,7 +50,7 @@ #endif #ifndef ETH_TYPE -#define ETH_TYPE ETH_PHY_LAN8720 // ETH.h eth_phy_type_t: 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110 +#define ETH_TYPE ETH_PHY_LAN8720 // ETH.h eth_phy_type_t: 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110, 2 = ETH_PHY_IP101 #endif #ifndef ETH_CLKMODE @@ -57,36 +58,22 @@ #endif */ -#ifndef ETH_POWER_PIN -#define ETH_POWER_PIN -1 -#endif - -#ifndef ETH_MDC_PIN -#define ETH_MDC_PIN 23 -#endif - -#ifndef ETH_MDIO_PIN -#define ETH_MDIO_PIN 18 -#endif - #include -struct { - char hostname[33]; -} Eth; +char eth_hostname[sizeof(my_hostname)]; void EthernetEvent(WiFiEvent_t event) { switch (event) { case SYSTEM_EVENT_ETH_START: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: " D_ATTEMPTING_CONNECTION)); - ETH.setHostname(Eth.hostname); + ETH.setHostname(eth_hostname); break; case SYSTEM_EVENT_ETH_CONNECTED: AddLog_P2(LOG_LEVEL_INFO, PSTR("ETH: " D_CONNECTED)); break; case SYSTEM_EVENT_ETH_GOT_IP: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: Mac %s, IPAddress %s, Hostname %s"), - ETH.macAddress().c_str(), ETH.localIP().toString().c_str(), Eth.hostname); + ETH.macAddress().c_str(), ETH.localIP().toString().c_str(), eth_hostname); /* if (ETH.fullDuplex()) { Serial.print(", FULL_DUPLEX"); @@ -95,6 +82,9 @@ void EthernetEvent(WiFiEvent_t event) { Serial.print(ETH.linkSpeed()); Serial.println("Mbps"); */ + Settings.ip_address[1] = (uint32_t)ETH.gatewayIP(); + Settings.ip_address[2] = (uint32_t)ETH.subnetMask(); + Settings.ip_address[3] = (uint32_t)ETH.dnsIP(); global_state.eth_down = 0; break; case SYSTEM_EVENT_ETH_DISCONNECTED: @@ -112,13 +102,20 @@ void EthernetEvent(WiFiEvent_t event) { void EthernetInit(void) { if (!Settings.flag4.network_ethernet) { return; } + if (!PinUsed(GPIO_ETH_PHY_MDC) && !PinUsed(GPIO_ETH_PHY_MDIO)) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: No ETH MDC and/or ETH MDIO GPIO defined")); + return; + } + +// snprintf_P(Eth.hostname, sizeof(Eth.hostname), PSTR("%s_eth"), my_hostname); + strlcpy(eth_hostname, my_hostname, sizeof(eth_hostname) -5); // Make sure there is room for "_eth" + strcat(eth_hostname, "_eth"); - snprintf_P(Eth.hostname, sizeof(Eth.hostname), PSTR("%s_eth"), my_hostname); WiFi.onEvent(EthernetEvent); - int eth_power = (PinUsed(GPIO_ETH_PHY_POWER)) ? Pin(GPIO_ETH_PHY_POWER) : ETH_POWER_PIN; - int eth_mdc = (PinUsed(GPIO_ETH_PHY_MDC)) ? Pin(GPIO_ETH_PHY_MDC) : ETH_MDC_PIN; - int eth_mdio = (PinUsed(GPIO_ETH_PHY_MDIO)) ? Pin(GPIO_ETH_PHY_MDIO) : ETH_MDIO_PIN; + int eth_power = (PinUsed(GPIO_ETH_PHY_POWER)) ? Pin(GPIO_ETH_PHY_POWER) : -1; + int eth_mdc = Pin(GPIO_ETH_PHY_MDC); + int eth_mdio = Pin(GPIO_ETH_PHY_MDIO); if (!ETH.begin(Settings.eth_address, eth_power, eth_mdc, eth_mdio, (eth_phy_type_t)Settings.eth_type, (eth_clock_mode_t)Settings.eth_clk_mode)) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: Bad PHY type or init error")); }; @@ -129,7 +126,7 @@ IPAddress EthernetLocalIP(void) { } char* EthernetHostname(void) { - return Eth.hostname; + return eth_hostname; } String EthernetMacAddress(void) { @@ -170,7 +167,7 @@ void CmndEthAddress(void) void CmndEthType(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { Settings.eth_type = XdrvMailbox.payload; restart_flag = 2; } diff --git a/tasmota/xnrg_13_fif_le01mr.ino b/tasmota/xnrg_13_fif_le01mr.ino index 71e77793a..f8d25e06f 100644 --- a/tasmota/xnrg_13_fif_le01mr.ino +++ b/tasmota/xnrg_13_fif_le01mr.ino @@ -127,15 +127,15 @@ void FifLEEvery250ms(void) } else { Energy.data_valid[0] = 0; - // SA=Slave Address, FC=Function Code, BC=Byte Count, B3..B0=Data byte, Ch Cl = crc16 checksum + // CA=Client Address, FC=Function Code, BC=Byte Count, B3..B0=Data byte, Ch Cl = crc16 checksum // U32 registers: // 00 01 02 03 04 05 06 07 08 - // SA FC BC B3 B2 B1 B0 Cl Ch + // CA FC BC B3 B2 B1 B0 Cl Ch // 01 03 04 00 00 00 72 7A 16 = REG[B3..B2=0x0139,B1..B0=0x013A] 114 = 0.114 A // 01 03 04 00 00 00 B0 FB 87 = REG[B3..B2=0xA01E,B1..B0=0xA01F] 176 = 1.76 kvarh // U16/S16 registers: // 00 01 02 03 04 05 06 - // SA FC BC B1 B0 Cl Ch + // CA FC BC B1 B0 Cl Ch // 01 03 02 5B 02 02 B5 = REG[B1..B0=0x0131] 23298 = 232.98 V // 01 03 02 03 E8 B8 FA = REG[B1..B0=0x0158] 1000 = 1.000 (power factor) // there are 3 data types used: diff --git a/tasmota/xsns_54_ina226.ino b/tasmota/xsns_54_ina226.ino index 725a63bb3..81c4bafc3 100644 --- a/tasmota/xsns_54_ina226.ino +++ b/tasmota/xsns_54_ina226.ino @@ -26,7 +26,7 @@ * 2. Configure the module to use I2C on the correct pins. * 3. Connect your ina226 module(s) to the I2C pins. * 4. Use the i2cscan console command to probe the modules and check they are present. -* 5. Enable the first device at I2C slave address 0x40 using the following console commands: +* 5. Enable the first device at I2C address 0x40 using the following console commands: * a. Sensor54 11 [shunt resistance in ohms] e.g. Sensor54 11 0.1 * b. Sensor54 12 [full scale current in amperes] e.g. Sensor54 12 3.0 * c. Sensor54 2 saves the settings and restarts Tasmota. The device should show up after the system boots again. @@ -35,7 +35,7 @@ * This driver will not probe I2C bus for INA226 devices unless the full scale current is set for a device number. * It will map device numbers as follows: * -* Device number to I2C slave address mapping +* Device number to I2C address mapping * * 1 - 0x40 * 2 - 0x41 @@ -59,7 +59,7 @@ * * Other commands * -* Sensor54 1 Rescan for devices and return the number of slaves found. +* Sensor54 1 Rescan for devices and return the number of INA226 found. * Sensor54 2 Save the configuration and restart * * @@ -88,13 +88,13 @@ #define INA226_REG_CALIBRATION (0x05) -typedef struct Ina226SlaveInfo_tag { +typedef struct Ina226Info_tag { uint8_t address; uint16_t calibrationValue; uint16_t config; uint8_t present : 1; float i_lsb; -} Ina226SlaveInfo_t; +} Ina226Info_t; /* * Program memory constants @@ -108,9 +108,9 @@ static const uint8_t PROGMEM probeAddresses[INA226_MAX_ADDRESSES] = {INA226_ADDR static char Ina226Str[] = "INA226"; -static uint8_t slavesFound = 0; +static uint8_t Ina226sFound = 0; static uint8_t schedule_reinit = 0; -static Ina226SlaveInfo_t slaveInfo[4] = {0}; +static Ina226Info_t Ina226Info[4] = {0}; //static uint16_t reinit_count[4]; static float voltages[4]; static float currents[4]; @@ -148,10 +148,10 @@ static uint32_t _expand_r_shunt(uint16_t compact_r_shunt) * Set calibration value for Ina226 */ -void Ina226SetCalibration(uint8_t slaveIndex) +void Ina226SetCalibration(uint8_t Ina226Index) { -Ina226SlaveInfo_t *si = slaveInfo + slaveIndex; +Ina226Info_t *si = Ina226Info + Ina226Index; I2cWrite16( si->address, INA226_REG_CALIBRATION, si->calibrationValue); @@ -167,10 +167,10 @@ bool Ina226TestPresence(uint8_t device) // Read config - uint16_t config = I2cRead16( slaveInfo[device].address, INA226_REG_CONFIG ); + uint16_t config = I2cRead16( Ina226Info[device].address, INA226_REG_CONFIG ); //AddLog_P2( LOG_LEVEL_NONE, PSTR("Config register %04x" ), config); - if (config != slaveInfo[device].config) + if (config != Ina226Info[device].config) return false; return true; @@ -179,10 +179,10 @@ bool Ina226TestPresence(uint8_t device) void Ina226ResetActive(void) { - Ina226SlaveInfo_t *p = slaveInfo; + Ina226Info_t *p = Ina226Info; for (uint32_t i = 0; i < INA226_MAX_ADDRESSES; i++) { - p = &slaveInfo[i]; + p = &Ina226Info[i]; // Address uint8_t addr = p->address; if (addr) { @@ -199,9 +199,9 @@ void Ina226Init() { uint32_t i; - slavesFound = 0; + Ina226sFound = 0; - Ina226SlaveInfo_t *p = slaveInfo; + Ina226Info_t *p = Ina226Info; //AddLog_P2( LOG_LEVEL_NONE, "Ina226Init"); // AddLog_P2( LOG_LEVEL_NONE, "Size of Settings: %d bytes", sizeof(Settings)); @@ -210,7 +210,7 @@ void Ina226Init() // AddLog_P2(LOG_LEVEL_DEBUG, "INA226: Initialization failed: No I2C support"); - // Clear slave info data + // Clear Ina226 info data for (i = 0; i < 4; i++){ *p = {0}; @@ -232,7 +232,7 @@ void Ina226Init() continue; - //AddLog_P2( LOG_LEVEL_NONE, PSTR("INA226 trying slave address %02x" ), addr ); + //AddLog_P2( LOG_LEVEL_NONE, PSTR("INA226 trying address %02x" ), addr ); // Try Resetting the device @@ -257,8 +257,8 @@ void Ina226Init() if (!I2cWrite16( addr, INA226_REG_CONFIG, config)) continue; // No device - // store data in slave info struct. - p = &slaveInfo[i]; + // store data in info struct. + p = &Ina226Info[i]; // Address p->address = addr; // Configuration @@ -282,7 +282,7 @@ void Ina226Init() I2cSetActiveFound(addr, Ina226Str); - slavesFound++; + Ina226sFound++; } } @@ -292,7 +292,7 @@ void Ina226Init() float Ina226ReadBus_v(uint8_t device) { - uint8_t addr = slaveInfo[device].address; + uint8_t addr = Ina226Info[device].address; int16_t reg_bus_v = I2cReadS16( addr, INA226_REG_BUSVOLTAGE); float result = ((float) reg_bus_v) * 0.00125f; @@ -307,10 +307,10 @@ float Ina226ReadBus_v(uint8_t device) float Ina226ReadShunt_i(uint8_t device) { - uint8_t addr = slaveInfo[device].address; + uint8_t addr = Ina226Info[device].address; int16_t reg_shunt_i = I2cReadS16( addr, INA226_REG_CURRENT); - float result = ((float) reg_shunt_i) * slaveInfo[device].i_lsb; + float result = ((float) reg_shunt_i) * Ina226Info[device].i_lsb; return result; } @@ -321,10 +321,10 @@ float Ina226ReadShunt_i(uint8_t device) float Ina226ReadPower_w(uint8_t device) { - uint8_t addr = slaveInfo[device].address; + uint8_t addr = Ina226Info[device].address; int16_t reg_shunt_i = I2cReadS16( addr, INA226_REG_POWER); - float result = ((float) reg_shunt_i) * (slaveInfo[device].i_lsb * 25.0); + float result = ((float) reg_shunt_i) * (Ina226Info[device].i_lsb * 25.0); return result; } @@ -354,19 +354,19 @@ void Ina226EverySecond() { //AddLog_P2( LOG_LEVEL_NONE, "Ina226EverySecond"); for (uint8_t device = 0; device < INA226_MAX_ADDRESSES; device++){ - // If there are slaves, and the device was present, and the device still is present, read its registers - if (slavesFound && slaveInfo[device].present && Ina226TestPresence(device)){ + // If there are Ina226s, and the device was present, and the device still is present, read its registers + if (Ina226sFound && Ina226Info[device].present && Ina226TestPresence(device)){ Ina226Read(device); } else { powers[device] = currents[device] = voltages[device] = 0.0f; // If device was present, note that it dropped off here - //if(slaveInfo[device].present){ + //if(Ina226Info[device].present){ //reinit_count[device]++; //AddLog_P2( LOG_LEVEL_DEBUG, "INA226 Device %d dropped off, count: %d", device, reinit_count[device]); //} // Device no longer present - slaveInfo[device].present = false; + Ina226Info[device].present = false; } } } @@ -413,7 +413,7 @@ bool Ina226CommandSensor() case 1: // Rerun init Ina226ResetActive(); Ina226Init(); - Response_P(PSTR("{\"Sensor54-Command-Result\":{\"SlavesFound\":%d}}"),slavesFound); + Response_P(PSTR("{\"Sensor54-Command-Result\":{\"Ina226sFound\":%d}}"),Ina226sFound); break; case 2: // Save and restart @@ -497,7 +497,7 @@ void Ina226Show(bool json) int i, num_found; for (num_found = 0, i = 0; i < INA226_MAX_ADDRESSES; i++) { // Skip uninstalled sensors - if (!slaveInfo[i].present) + if (!Ina226Info[i].present) continue; num_found++; diff --git a/tasmota/xsns_61_MI_NRF24.ino b/tasmota/xsns_61_MI_NRF24.ino index 5dd82f3a5..4fb261751 100644 --- a/tasmota/xsns_61_MI_NRF24.ino +++ b/tasmota/xsns_61_MI_NRF24.ino @@ -21,6 +21,8 @@ Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 0.9.6.0 20200618 integrate - add decryption for LYWSD03 + --- 0.9.5.0 20200328 integrate - add dew point, multi-page-web ui, refactoring, command interface, simple beacon --- @@ -62,6 +64,7 @@ #define XSNS_61 61 #include +#include #define FLORA 1 #define MJ_HT_V1 2 @@ -74,14 +77,15 @@ const char S_JSON_NRF_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_NRF "%s\":%d}"; const char S_JSON_NRF_COMMAND[] PROGMEM = "{\"" D_CMND_NRF "%s\":\"%s\"}"; -const char kNRF_Commands[] PROGMEM = "Ignore|Page|Scan|Beacon|Chan"; +const char kNRF_Commands[] PROGMEM = "Ignore|Page|Scan|Beacon|Chan|Key"; enum NRF_Commands { // commands useable in console or rules CMND_NRF_IGNORE, // ignore specific sensor type (1-6) CMND_NRF_PAGE, // sensor entries per web page, which will be shown alternated CMND_NRF_SCAN, // simplified passive BLE adv scan CMND_NRF_BEACON, // even more simplified Beacon, reports time since last sighting - CMND_NRF_CHAN // ignore channel 0-2 (translates to 37-39) + CMND_NRF_CHAN, // ignore channel 0-2 (translates to 37-39) + CMND_NRF_KEY // add bind_key to a MAC for payload decryption }; const uint16_t kMINRFSlaveID[6]={ 0x0098, // Flora @@ -104,8 +108,8 @@ const char * kMINRFSlaveType[] PROGMEM = {kMINRFSlaveType1,kMINRFSlaveType2,kMIN const uint32_t kMINRFFloPDU[3] = {0x3eaa857d,0xef3b8730,0x71da7b46}; const uint32_t kMINRFMJPDU[3] = {0x4760cd66,0xdbcc0cd3,0x33048df5}; const uint32_t kMINRFL2PDU[3] = {0x3eaa057d,0xef3b0730,0x71dafb46}; -// const uint32_t kMINRFL3PDU[3] = {0x4760dd78,0xdbcc1ccd,0xffffffff}; //encrypted - 58 58 -const uint32_t kMINRFL3PDU[3] = {0x4760cb78,0xdbcc0acd,0x33048beb}; //unencrypted - 30 58 +const uint32_t kMINRFL3PDU[3] = {0x4760dd78,0xdbcc1ccd,0x33049deb}; //encrypted - 58 58 +// const uint32_t kMINRFL3PDU[3] = {0x4760cb78,0xdbcc0acd,0x33048beb}; //unencrypted - 30 58 const uint32_t kMINRFCGGPDU[3] = {0x4760cd6e,0xdbcc0cdb,0x33048dfd}; const uint32_t kMINRFCGDPDU[3] = {0x5da0d752,0xc10c16e7,0x29c497c1}; @@ -155,6 +159,28 @@ struct bleAdvPacket_t { // for nRF24L01 max 32 bytes = 2+6+24 uint8_t mac[6]; }; +struct encPayload_t { + uint8_t cipher[5]; + uint8_t ExtCnt[3]; + uint8_t tag[4]; +}; + +struct encPacket_t{ + // the packet is longer, but this part is enough to decrypt + uint16_t PID; + uint8_t frameCnt; + uint8_t MAC[6]; + encPayload_t payload; +}; + +union mi_bindKey_t{ + struct{ + uint8_t key[16]; + uint8_t MAC[6]; + }; + uint8_t buf[22]; +}; + union FIFO_t{ bleAdvPacket_t bleAdv; mi_beacon_t miBeacon; @@ -223,6 +249,7 @@ struct scan_entry_t { std::vector MIBLEsensors; std::vector MINRFscanResult; +std::vector MIBLEbindKeys; static union{ scan_entry_t MINRFdummyEntry; @@ -564,6 +591,61 @@ void MINRFcomputeBeaconPDU(void){ } } +int MINRFdecryptPacket(char *_buf){ + encPacket_t *packet = (encPacket_t*)_buf; + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("to decrypt: %02x %02x %02x %02x %02x %02x %02x %02x"),(uint8_t)_buf[0],(uint8_t)_buf[1],(uint8_t)_buf[2],(uint8_t)_buf[3],(uint8_t)_buf[4],(uint8_t)_buf[5],(uint8_t)_buf[6],(uint8_t)_buf[7]); + + int ret = 0; + unsigned char output[10] = {0}; + uint8_t nonce[12]; + const unsigned char authData[1] = {0x11}; + + // nonce: device MAC, device type, frame cnt, ext. cnt + for (uint32_t i = 0; i<6; i++){ + nonce[i] = packet->MAC[5-i]; + } + memcpy((uint8_t*)&nonce+6,(uint8_t*)&packet->PID,2); + nonce[8] = packet->frameCnt; + memcpy((uint8_t*)&nonce+9,(uint8_t*)&packet->payload.ExtCnt,3); + + uint8_t _bindkey[16] = {0x0}; + for(uint32_t i=0; iMAC,MIBLEbindKeys[i].MAC,sizeof(packet->MAC))==0){ + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("have key")); + memcpy(_bindkey,MIBLEbindKeys[i].key,sizeof(_bindkey)); + break; + } + // else{ + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mac in packet: %02x %02x %02x %02x %02x %02x"), packet->MAC[0], packet->MAC[1], packet->MAC[2], packet->MAC[3], packet->MAC[4], packet->MAC[5]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mac in vector: %02x %02x %02x %02x %02x %02x"), MIBLEbindKeys[i].MAC[0], MIBLEbindKeys[i].MAC[1], MIBLEbindKeys[i].MAC[2], MIBLEbindKeys[i].MAC[3], MIBLEbindKeys[i].MAC[4], MIBLEbindKeys[i].MAC[5]); + // } + } + // init + mbedtls_ccm_context ctx; + mbedtls_ccm_init(&ctx); + + // set bind key + ret = mbedtls_ccm_setkey(&ctx, + MBEDTLS_CIPHER_ID_AES, + _bindkey, + 16 * 8 //bits + ); + + ret = mbedtls_ccm_auth_decrypt(&ctx,5, + (const unsigned char*)&nonce, sizeof(nonce), + authData, sizeof(authData), + packet->payload.cipher, output, + packet->payload.tag,sizeof(packet->payload.tag)); + + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Err:%i, Decrypted : %02x %02x %02x %02x %02x "), ret, output[0],output[1],output[2],output[3],output[4]); + // put decrypted data in place + memcpy((uint8_t*)(packet->payload.cipher)+1,output,sizeof(packet->payload.cipher)); + // clean up + mbedtls_ccm_free(&ctx); + return ret; +} + + /*********************************************************************************************\ * helper functions \*********************************************************************************************/ @@ -581,6 +663,46 @@ void MINRFreverseMAC(uint8_t _mac[]){ memcpy(_mac,_reversedMAC, sizeof(_reversedMAC)); } +void MINRFAddKey(char* payload){ + mi_bindKey_t keyMAC; + memset(keyMAC.buf,0,sizeof(keyMAC)); + MINRFKeyMACStringToBytes(payload,keyMAC.buf); + bool unknownKey = true; + for(uint32_t i=0; i= '0' && c <= '9') + value = (c - '0'); + else if (c >= 'A' && c <= 'F') + value = (10 + (c - 'A')); + _keyMac[(index/2)] += value << (((index + 1) % 2) * 4); + index++; + } + DEBUG_SENSOR_LOG(PSTR("MINRF: %s to:"),_string); + DEBUG_SENSOR_LOG(PSTR("MINRF: key-array: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"),_keyMac[0],_keyMac[1],_keyMac[2],_keyMac[3],_keyMac[4],_keyMac[5],_keyMac[6],_keyMac[7],_keyMac[8],_keyMac[9],_keyMac[10],_keyMac[11],_keyMac[12],_keyMac[13],_keyMac[14],_keyMac[15]); + DEBUG_SENSOR_LOG(PSTR("MINRF: MAC-array: %02X%02X%02X%02X%02X%02X"),_keyMac[16],_keyMac[17],_keyMac[18],_keyMac[19],_keyMac[20],_keyMac[21]); +} + /** * @brief * @@ -754,14 +876,19 @@ void MINRFhandleMiBeaconPacket(void){ uint32_t _slot = MINRFgetSensorSlot(MINRF.buffer.miBeacon.Mac, MINRF.buffer.miBeacon.productID); if(_slot==0xff) return; DEBUG_SENSOR_LOG(PSTR("MINRF: slot %u, size vector: %u %u"),_slot,MIBLEsensors.size()); - mi_sensor_t *_sensorVec = &MIBLEsensors.at(_slot); + DEBUG_SENSOR_LOG(PSTR("MINRF: %u %u %u"),_slot,_sensorVec->type,MINRF.buffer.miBeacon.type); float _tempFloat; if (_sensorVec->type==MJ_HT_V1 || _sensorVec->type==CGG1){ memcpy(MINRFtempBuf,(uint8_t*)&MINRF.buffer.miBeacon.spare, 32-9); // shift by one byte for the MJ_HT_V1 and CGG1 memcpy((uint8_t*)&MINRF.buffer.miBeacon.type,MINRFtempBuf, 32-9); // shift by one byte for the MJ_HT_V1 and CGG1 } + if(_sensorVec->type==LYWSD03){ + int decryptRet = -1; + decryptRet = MINRFdecryptPacket((char*)&MINRF.buffer); //start with PID + if(decryptRet==0) _sensorVec->showedUp=255; // if decryption worked, this must be a valid sensor + } DEBUG_SENSOR_LOG(PSTR("%s at slot %u"), kNRFSlaveType[_sensorVec->type-1],_slot); switch(MINRF.buffer.miBeacon.type){ @@ -823,21 +950,6 @@ void MINRFhandleMiBeaconPacket(void){ break; } } -/** - * @brief more or less a placeholder, at least it is technically possible to really decrypt data, but - * the bind_key must be retrieved with 3rd-party-tools -> TODO - */ -void MINRFhandleLYWSD03Packet(void){ - // not much to do ATM, just show the sensor without data - MINRFreverseMAC(MINRF.buffer.miBeacon.Mac); - uint32_t _slot = MINRFgetSensorSlot(MINRF.buffer.miBeacon.Mac, MINRF.buffer.miBeacon.productID); - DEBUG_SENSOR_LOG(PSTR("MINRF: Sensor slot: %u"), _slot); - if(_slot==0xff) return; - - MINRF_LOG_BUFFER(MINRF.streamBuffer); - MINRF_LOG_BUFFER(MINRF.lsfrBuffer); - MINRF_LOG_BUFFER(MINRF.buffer.raw); -} /** * @brief parse the Cleargrass-packet @@ -901,12 +1013,9 @@ void MINRF_EVERY_50_MSECOND() { // Every 50mseconds } else MINRFhandleScan(); break; - case FLORA: case MJ_HT_V1: case LYWSD02: case CGG1: + case FLORA: case MJ_HT_V1: case LYWSD02: case CGG1: case LYWSD03: MINRFhandleMiBeaconPacket(); break; - case LYWSD03: - MINRFhandleLYWSD03Packet(); - break; case CGD1: MINRFhandleCGD1Packet(); break; @@ -1026,6 +1135,12 @@ bool NRFCmd(void) { } Response_P(S_JSON_NRF_COMMAND_NVALUE, command, MINRF.channelIgnore); break; + case CMND_NRF_KEY: + if (XdrvMailbox.data_len==44){ // a KEY-MAC-string + MINRFAddKey(XdrvMailbox.data); + Response_P(S_JSON_NRF_COMMAND, command, XdrvMailbox.data); + } + break; default: // else for Unknown command serviced = false; @@ -1191,5 +1306,3 @@ bool Xsns61(uint8_t function) #endif // USE_MIBLE #endif // USE_NRF24 #endif // USE_SPI - - diff --git a/tasmota/xsns_74_lmt01.ino b/tasmota/xsns_74_lmt01.ino new file mode 100644 index 000000000..8bd23ca4a --- /dev/null +++ b/tasmota/xsns_74_lmt01.ino @@ -0,0 +1,142 @@ +/* + xns_74_lmt01.ino - Support for single wire LMT01 Temperature Sensor + + Copyright (C) 2020 Theo Arends, Justifiably + + This program 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 3 of the License, or + (at your option) any later version. + + This program 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, see . +*/ + +#ifdef USE_LMT01 +/*********************************************************************************************\ + * LMT01 - 0.5°C Accurate 2-Pin Digital Output Temperature Sensor With Pulse Count Interface + * + * Uses fragments of public domain code LMT01_Example.ino released by Texas Instruments, July 10th 2017. + * See https://training.ti.com/how-interface-lmt01-temperature-sensor-arduino +\*********************************************************************************************/ + +#define XSNS_74 74 + +#define LMT01_TIMEOUT 200 // ms timeout for a reading cycle + +bool lmt01_initialized = false; +float lmt01_temperature = NAN; + +void LMT01_Init(void) { + if (PinUsed(GPIO_LMT01)) { + pinMode(Pin(GPIO_LMT01), INPUT); + attachInterrupt(Pin(GPIO_LMT01), LMT01_countPulse, FALLING); + lmt01_initialized = true; + } +} + +#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception +void LMT01_countPulse(void) ICACHE_RAM_ATTR; +#endif // ARDUINO_ESP8266_RELEASE_2_3_0 + +volatile int lmt01_pulseCount = 0; + +void LMT01_countPulse(void) { + lmt01_pulseCount++; +} + +void LMT01_GetTemperature(void) { + int pulses = 0; + pulses = LMT01_getPulses(); + if (pulses >= 0) { + // simple linear conversion, datasheet has a look-up table alternative + // which is accurate over a wider temperature range + lmt01_temperature = ConvertTemp(0.0625 * pulses - 50); + } else { + lmt01_temperature = NAN; // Timeout + } +} + +int LMT01_getPulses(void) { + int timeout = LMT01_TIMEOUT; + int hold = -1; + // complete current pulse cycle (50ms max) + while(lmt01_pulseCount != hold && --timeout > 0) { + hold = lmt01_pulseCount; + delay(1); + } + lmt01_pulseCount = 0; + // wait for start of next (54ms max) + while(lmt01_pulseCount == 0 && --timeout > 0) { + delay(1); + } + hold = -1; + // take this count (up to 50ms) + while(lmt01_pulseCount != hold && --timeout > 0) { + hold = lmt01_pulseCount; + delay(1); + } + if (timeout > 0) { + return hold; + } + return -1; +} + +void LMT01_Show(bool Json) { + char temp[33]; + dtostrfd(lmt01_temperature, Settings.flag2.temperature_resolution, temp); + + if (Json) { + ResponseAppend_P(JSON_SNS_TEMP, "LMT01", temp); +#ifdef USE_DOMOTICZ + if (0 == tele_period) { + DomoticzSensor(DZ_TEMP, temp); + } +#endif // USE_DOMOTICZ +#ifdef USE_KNX + if (0 == tele_period) { + KnxSensor(KNX_TEMPERATURE, lmt01_temperature); + } +#endif // USE_KNX +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_TEMP, "LMT01", temp, TempUnit()); +#endif // USE_WEBSERVER + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns74(uint8_t function) +{ + bool result = false; + + if (FUNC_INIT == function) { + LMT01_Init(); + } + else if (lmt01_initialized) { + switch (function) { + case FUNC_EVERY_SECOND: + LMT01_GetTemperature(); + break; + case FUNC_JSON_APPEND: + LMT01_Show(true); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + LMT01_Show(false); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_LMT01 diff --git a/tools/decode-status.py b/tools/decode-status.py index d0be84459..cdceced48 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -206,7 +206,7 @@ a_features = [[ "USE_IAQ","USE_DISPLAY_SEVENSEG","USE_AS3935","USE_PING", "USE_WINDMETER","USE_OPENTHERM","USE_THERMOSTAT","USE_VEML6075", "USE_VEML7700","USE_MCP9808","USE_BL0940","USE_TELEGRAM", - "USE_HP303B","USE_TCP_BRIDGE","","", + "USE_HP303B","USE_TCP_BRIDGE","USE_TELEINFO","USE_LMT01", "","","","", "","","","", "","","USE_ETHERNET","USE_WEBCAM" @@ -243,7 +243,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v20200611 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v20200617 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj))