feat(util): Add ARC4 algorithm to util

This commit is contained in:
yuanjm
2019-08-02 18:01:34 +08:00
parent 6f86c07c49
commit 98a46e435f
4 changed files with 251 additions and 0 deletions

View File

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

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