Merge branch 'feature/add_rc4_algorithm_in_util' into 'master'

feat(util): Add ARC4 for ESP8266 SoC

See merge request sdk/ESP8266_RTOS_SDK!1028
This commit is contained in:
Dong Heng
2019-08-07 12:11:31 +08:00
6 changed files with 302 additions and 1 deletions

View File

@ -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

View File

@ -275,7 +275,6 @@
* digests and ciphers instead. * digests and ciphers instead.
* *
*/ */
//#define MBEDTLS_ARC4_ALT
//#define MBEDTLS_BLOWFISH_ALT //#define MBEDTLS_BLOWFISH_ALT
//#define MBEDTLS_CAMELLIA_ALT //#define MBEDTLS_CAMELLIA_ALT
//#define MBEDTLS_CCM_ALT //#define MBEDTLS_CCM_ALT
@ -303,6 +302,11 @@
#ifdef CONFIG_ESP_MD5 #ifdef CONFIG_ESP_MD5
#define MBEDTLS_MD5_ALT #define MBEDTLS_MD5_ALT
#endif #endif
#ifdef CONFIG_ESP_ARC4
#define MBEDTLS_ARC4_ALT
#endif
/* /*
* When replacing the elliptic curve module, pleace consider, that it is * When replacing the elliptic curve module, pleace consider, that it is
* implemented with two .c files: * implemented with two .c files:

View File

@ -51,4 +51,19 @@ config ESP_MD5
Disabling the "assert" function at menuconfig can speed up the calculation. 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 endmenu # Util

View File

@ -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 <stdint.h>
#include <stddef.h>
#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

View File

@ -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 <sys/errno.h>
#include <string.h>
#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);
}

View File

@ -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 <string.h>
#include <stdio.h>
#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