diff --git a/components/ssl/mbedtls/port/esp8266/include/arc4_alt.h b/components/ssl/mbedtls/port/esp8266/include/arc4_alt.h new file mode 100644 index 00000000..1fe52e57 --- /dev/null +++ b/components/ssl/mbedtls/port/esp8266/include/arc4_alt.h @@ -0,0 +1,46 @@ +/* + * 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. + * + * + */ +#ifndef ARC4_ALT_H +#define ARC4_ALT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(MBEDTLS_ARC4_ALT) +#include "esp_arc4.h" + +typedef esp_arc4_context mbedtls_arc4_context; + +#define mbedtls_arc4_init(_ctx) { } + +#define mbedtls_arc4_free(_ctx) { } + +#define mbedtls_arc4_setup(_ctx, _s, _l) esp_arc4_setup(_ctx, _s, _l) + +#define mbedtls_arc4_crypt(_ctx, _l, _i, _o) esp_arc4_encrypt(_ctx, _l, _i, _o) + +#endif /* MBEDTLS_ARC4_ALT */ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/components/ssl/mbedtls/port/esp8266/include/mbedtls/esp_config.h b/components/ssl/mbedtls/port/esp8266/include/mbedtls/esp_config.h index 6243a73b..8a9af79b 100644 --- a/components/ssl/mbedtls/port/esp8266/include/mbedtls/esp_config.h +++ b/components/ssl/mbedtls/port/esp8266/include/mbedtls/esp_config.h @@ -275,7 +275,6 @@ * digests and ciphers instead. * */ -//#define MBEDTLS_ARC4_ALT //#define MBEDTLS_BLOWFISH_ALT //#define MBEDTLS_CAMELLIA_ALT //#define MBEDTLS_CCM_ALT @@ -303,6 +302,11 @@ #ifdef CONFIG_ESP_MD5 #define MBEDTLS_MD5_ALT #endif + +#ifdef CONFIG_ESP_ARC4 +#define MBEDTLS_ARC4_ALT +#endif + /* * When replacing the elliptic curve module, pleace consider, that it is * implemented with two .c files: diff --git a/components/util/Kconfig b/components/util/Kconfig index 620a46ad..cb741d4e 100644 --- a/components/util/Kconfig +++ b/components/util/Kconfig @@ -51,4 +51,19 @@ config ESP_MD5 Disabling the "assert" function at menuconfig can speed up the calculation. +config ESP_ARC4 + bool "Enable Espressif ARC4" + default y + help + Enable Espressif ARC4 for other components to + speed up process speed and save code size. + + ESP8285 is like ESP8266 + 1MB flash, but its internal I/O connection from CPU + core to flash is DIO not QIO, which makes it read flash data slower. + So the function will speed up ESP8285 obviously. + + The calculation uses "ibus_data" to speed up load data from instruction bus. + + Disabling the "assert" function at menuconfig can speed up the calculation. + endmenu # Util diff --git a/components/util/include/esp_arc4.h b/components/util/include/esp_arc4.h new file mode 100644 index 00000000..69e694a3 --- /dev/null +++ b/components/util/include/esp_arc4.h @@ -0,0 +1,71 @@ +// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD +// +// 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. + +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +/** + * @brief ARC4 context structure + */ +typedef struct +{ + int x; /*!< permutation index */ + int y; /*!< permutation index */ + unsigned char m[256]; /*!< permutation table */ +}esp_arc4_context; + +/** + * @brief ARC4 key schedule + * + * @param ctx ARC4 context to be setup + * @param key the secret key + * @param keylen length of the key, in bytes + */ +void esp_arc4_setup(esp_arc4_context *ctx, const uint8_t *key, uint32_t keylen); + +/** + * @brief ARC4 cipher function + * + * @param ctx ARC4 context + * @param length length of the input data + * @param input buffer holding the input data + * @param output buffer for the output data + * + * @return 0 if successful + */ +int esp_arc4_encrypt(esp_arc4_context *ctx, size_t length, const uint8_t *input, uint8_t *output); + +/** + * @brief ARC4 cipher function + * + * @param ctx ARC4 context + * @param length length of the input data + * @param input buffer holding the input data + * @param output buffer for the output data + * + * @return 0 if successful + * @Note When you encrypt or decrypt, must call esp_arc4_setup function to set key. + * Encrypt and decrypt will change the ctx value + */ +int esp_arc4_decrypt(esp_arc4_context *ctx, size_t length, const uint8_t *input, uint8_t *output ); + +#ifdef __cplusplus +} +#endif + diff --git a/components/util/src/arc4.c b/components/util/src/arc4.c new file mode 100644 index 00000000..86569239 --- /dev/null +++ b/components/util/src/arc4.c @@ -0,0 +1,91 @@ +// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD +// +// 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. + +#include +#include +#include "esp_arc4.h" +#include "ibus_data.h" +#include "util_assert.h" + +/* + * ARC4 key schedule + */ +void esp_arc4_setup(esp_arc4_context *ctx, const uint8_t *key, uint32_t keylen) +{ + int i, j, a; + uint32_t k; + uint8_t *m; + + util_assert(ctx); + util_assert(key); + + ctx->x = 0; + ctx->y = 0; + m = ctx->m; + + for(i = 0; i < 256; i++) + m[i] = (uint8_t) i; + + j = k = 0; + + for(i = 0; i < 256; i++, k++) + { + if(k >= keylen) k = 0; + + a = m[i]; + j = (j + a + key[k]) & 0xFF; + m[i] = m[j]; + m[j] = (uint8_t) a; + } +} + +/* + * ARC4 cipher function + */ +int esp_arc4_encrypt(esp_arc4_context *ctx, size_t length, const uint8_t *input, uint8_t *output) +{ + int x, y, a, b; + size_t i; + uint8_t *m; + + util_assert(ctx); + util_assert(input); + util_assert(output); + + x = ctx->x; + y = ctx->y; + m = ctx->m; + + for(i = 0; i < length; i++) + { + x = (x + 1) & 0xFF; a = m[x]; + y = (y + a) & 0xFF; b = m[y]; + + m[x] = (uint8_t) b; + m[y] = (uint8_t) a; + + output[i] = (uint8_t)(input[i] ^ m[(uint8_t)(a + b)]); + } + + ctx->x = x; + ctx->y = y; + + return 0; +} + +int esp_arc4_decrypt(esp_arc4_context *ctx, size_t length, const uint8_t *input, uint8_t *output) +{ + return esp_arc4_encrypt(ctx, length, input, output); +} + diff --git a/components/util/test/test_arc4.c b/components/util/test/test_arc4.c new file mode 100644 index 00000000..9e43243b --- /dev/null +++ b/components/util/test/test_arc4.c @@ -0,0 +1,74 @@ + +// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD +// +// 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. + +#include +#include +#include "esp_arc4.h" +#include "unity.h" + +#define TEST_ARC4_COUNT 512 +#define TEST_ARC4_DEBUG 1 + +static const uint8_t arc4_test_key[3][8] = +{ + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +static const uint8_t arc4_test_pt[3][8] = +{ + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +static const uint8_t arc4_test_ct[3][8] = +{ + { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 }, + { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 }, + { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A } +}; + +TEST_CASE("Test ARC4", "[ARC4]") +{ + int i, n = 0; + uint32_t encode_time = 0; + uint8_t ibuf[8]; + uint8_t obuf[8]; + extern uint32_t esp_get_time(void); + + for (n = 0; n < TEST_ARC4_COUNT; n++) { + for(i = 0; i < 3; i++) + { + memcpy(ibuf, arc4_test_pt[i], 8); + + uint32_t tmp = esp_get_time(); + esp_arc4_context ctx; + esp_arc4_setup(&ctx, arc4_test_key[i], 8); + TEST_ASSERT_TRUE(esp_arc4_encrypt(&ctx, 8, ibuf, obuf) == 0); + encode_time += esp_get_time() - tmp; + + TEST_ASSERT_TRUE(memcmp(obuf, arc4_test_ct[i], 8) == 0); + } + } +#if TEST_ARC4_DEBUG + printf("ARC4 test cost time totally encode %u us , once cost is about encode %u us\n", + encode_time, encode_time / (TEST_ARC4_COUNT * 3)); +#endif +} + +// ARC4 test cost time totally encode 794288 us , once cost is about encode 517 us +