mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'master' into feature/btdm_bluedroid
# Conflicts: # components/esp32/cpu_freq.c # components/esp32/lib
This commit is contained in:
commit
5a9801aca7
@ -46,6 +46,10 @@ build_template_app:
|
||||
- sed -i.bak -e's/CONFIG_OPTIMIZATION_LEVEL_DEBUG\=y/CONFIG_OPTIMIZATION_LEVEL_RELEASE=y/' sdkconfig
|
||||
- make defconfig
|
||||
- make all V=1
|
||||
# Check if there are any stray printf/ets_printf references in WiFi libs
|
||||
- cd ../components/esp32/lib
|
||||
- test $(xtensa-esp32-elf-nm *.a | grep -w printf | wc -l) -eq 0
|
||||
- test $(xtensa-esp32-elf-nm *.a | grep -w ets_printf | wc -l) -eq 0
|
||||
|
||||
|
||||
.build_gitlab: &build_template
|
||||
@ -88,7 +92,7 @@ build_esp_idf_tests:
|
||||
- cd tools/unit-test-app
|
||||
- git checkout ${CI_BUILD_REF_NAME} || echo "Using default branch..."
|
||||
- make defconfig
|
||||
- make
|
||||
- make TESTS_ALL=1
|
||||
|
||||
build_examples:
|
||||
<<: *build_template
|
||||
@ -288,7 +292,7 @@ deploy_docs:
|
||||
variables:
|
||||
# jobs MUST set CONFIG_FILE in before_script, and overwrite the variables above if necessary
|
||||
LOCAL_ENV_CONFIG_PATH: /home/gitlab-runner/LocalConfig/ESP32_IDF
|
||||
BIN_PATH: "$CI_PROJECT_DIR/esp-idf-tests/build/"
|
||||
BIN_PATH: "$CI_PROJECT_DIR/tools/unit-test-app/build/"
|
||||
LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF"
|
||||
APP_NAME: "ut"
|
||||
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/unit_test"
|
||||
|
5
components/app_update/component.mk
Executable file
5
components/app_update/component.mk
Executable file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# Component Makefile
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
|
381
components/app_update/esp_ota_ops.c
Normal file
381
components/app_update/esp_ota_ops.c
Normal file
@ -0,0 +1,381 @@
|
||||
// Copyright 2015-2016 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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_partition.h"
|
||||
#include "esp_spi_flash.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "esp_ota_ops.h"
|
||||
#include "rom/queue.h"
|
||||
#include "rom/crc.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
|
||||
#define OTA_MAX(a,b) ((a) >= (b) ? (a) : (b))
|
||||
#define OTA_MIN(a,b) ((a) <= (b) ? (a) : (b))
|
||||
#define SUB_TYPE_ID(i) (i & 0x0F)
|
||||
|
||||
typedef struct ota_ops_entry_ {
|
||||
uint32_t handle;
|
||||
esp_partition_t part;
|
||||
uint32_t erased_size;
|
||||
uint32_t wrote_size;
|
||||
LIST_ENTRY(ota_ops_entry_) entries;
|
||||
} ota_ops_entry_t;
|
||||
|
||||
/* OTA selection structure (two copies in the OTA data partition.)
|
||||
Size of 32 bytes is friendly to flash encryption */
|
||||
typedef struct {
|
||||
uint32_t ota_seq;
|
||||
uint8_t seq_label[24];
|
||||
uint32_t crc; /* CRC32 of ota_seq field only */
|
||||
} ota_select;
|
||||
|
||||
static LIST_HEAD(ota_ops_entries_head, ota_ops_entry_) s_ota_ops_entries_head =
|
||||
LIST_HEAD_INITIALIZER(s_ota_ops_entries_head);
|
||||
|
||||
static uint32_t s_ota_ops_last_handle = 0;
|
||||
static ota_select s_ota_select[2];
|
||||
|
||||
const static char *TAG = "esp_ota_ops";
|
||||
|
||||
esp_err_t esp_ota_begin(const esp_partition_t *partition, size_t image_size, esp_ota_handle_t *out_handle)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if ((partition == NULL) || (out_handle == NULL)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ota_ops_entry_t *new_entry = (ota_ops_entry_t *) calloc(sizeof(ota_ops_entry_t), 1);
|
||||
|
||||
if (new_entry == 0) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
// if input image size is 0 or OTA_SIZE_UNKNOWN, will erase all areas in this partition
|
||||
if ((image_size == 0) || (image_size == OTA_SIZE_UNKNOWN)) {
|
||||
ret = esp_partition_erase_range(partition, 0, partition->size);
|
||||
} else {
|
||||
ret = esp_partition_erase_range(partition, 0, (image_size / SPI_FLASH_SEC_SIZE + 1) * SPI_FLASH_SEC_SIZE);
|
||||
}
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
free(new_entry);
|
||||
new_entry = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
LIST_INSERT_HEAD(&s_ota_ops_entries_head, new_entry, entries);
|
||||
|
||||
if ((image_size == 0) || (image_size == OTA_SIZE_UNKNOWN)) {
|
||||
new_entry->erased_size = partition->size;
|
||||
} else {
|
||||
new_entry->erased_size = image_size;
|
||||
}
|
||||
|
||||
memcpy(&new_entry->part, partition, sizeof(esp_partition_t));
|
||||
new_entry->handle = ++s_ota_ops_last_handle;
|
||||
*out_handle = new_entry->handle;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
|
||||
{
|
||||
esp_err_t ret;
|
||||
ota_ops_entry_t *it;
|
||||
|
||||
if (data == NULL) {
|
||||
ESP_LOGE(TAG, "write data is invalid");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// find ota handle in linked list
|
||||
for (it = LIST_FIRST(&s_ota_ops_entries_head); it != NULL; it = LIST_NEXT(it, entries)) {
|
||||
if (it->handle == handle) {
|
||||
// must erase the partition before writing to it
|
||||
assert(it->erased_size > 0 && "must erase the partition before writing to it");
|
||||
ret = esp_partition_write(&it->part, it->wrote_size, data, size);
|
||||
if(ret == ESP_OK){
|
||||
it->wrote_size += size;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
//if go to here ,means don't find the handle
|
||||
ESP_LOGE(TAG,"not found the handle")
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_end(esp_ota_handle_t handle)
|
||||
{
|
||||
esp_err_t ret;
|
||||
ota_ops_entry_t *it;
|
||||
size_t image_size;
|
||||
for (it = LIST_FIRST(&s_ota_ops_entries_head); it != NULL; it = LIST_NEXT(it, entries)) {
|
||||
if (it->handle == handle) {
|
||||
// an ota handle need to be ended after erased and wrote data in it
|
||||
if ((it->erased_size == 0) || (it->wrote_size == 0)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECUREBOOTLOADER
|
||||
if (esp_image_basic_verify(it->part.address, &image_size) != ESP_OK) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
ret = esp_secure_boot_verify_signature(it->part.address, image_size);
|
||||
if (ret != ESP_OK) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
#endif
|
||||
|
||||
LIST_REMOVE(it, entries);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (it == NULL) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
free(it);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static uint32_t ota_select_crc(const ota_select *s)
|
||||
{
|
||||
return crc32_le(UINT32_MAX, (uint8_t *)&s->ota_seq, 4);
|
||||
}
|
||||
|
||||
static bool ota_select_valid(const ota_select *s)
|
||||
{
|
||||
return s->ota_seq != UINT32_MAX && s->crc == ota_select_crc(s);
|
||||
}
|
||||
|
||||
static esp_err_t rewrite_ota_seq(uint32_t seq, uint8_t sec_id, const esp_partition_t *ota_data_partition)
|
||||
{
|
||||
esp_err_t ret;
|
||||
|
||||
if (sec_id == 0 || sec_id == 1) {
|
||||
s_ota_select[sec_id].ota_seq = seq;
|
||||
s_ota_select[sec_id].crc = ota_select_crc(&s_ota_select[sec_id]);
|
||||
ret = spi_flash_erase_range(ota_data_partition->address, SPI_FLASH_SEC_SIZE);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
} else {
|
||||
return esp_partition_write(ota_data_partition, SPI_FLASH_SEC_SIZE * sec_id, &s_ota_select[sec_id].ota_seq, sizeof(ota_select));
|
||||
}
|
||||
} else {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t get_ota_partition_count(void)
|
||||
{
|
||||
uint16_t ota_app_count = 0;
|
||||
while (esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ota_app_count, NULL) != NULL) {
|
||||
assert(ota_app_count < 16 && "must erase the partition before writing to it");
|
||||
ota_app_count++;
|
||||
}
|
||||
return ota_app_count;
|
||||
}
|
||||
|
||||
static esp_err_t esp_rewrite_ota_data(esp_partition_subtype_t subtype)
|
||||
{
|
||||
esp_err_t ret;
|
||||
const esp_partition_t *find_partition = NULL;
|
||||
uint16_t ota_app_count = 0;
|
||||
uint32_t i = 0;
|
||||
uint32_t seq;
|
||||
static spi_flash_mmap_memory_t ota_data_map;
|
||||
const void *result = NULL;
|
||||
|
||||
find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
if (find_partition != NULL) {
|
||||
ota_app_count = get_ota_partition_count();
|
||||
//esp32_idf use two sector for store information about which partition is running
|
||||
//it defined the two sector as ota data partition,two structure ota_select is saved in the two sector
|
||||
//named data in first sector as s_ota_select[0], second sector data as s_ota_select[1]
|
||||
//e.g.
|
||||
//if s_ota_select[0].ota_seq == s_ota_select[1].ota_seq == 0xFFFFFFFF,means ota info partition is in init status
|
||||
//so it will boot factory application(if there is),if there's no factory application,it will boot ota[0] application
|
||||
//if s_ota_select[0].ota_seq != 0 and s_ota_select[1].ota_seq != 0,it will choose a max seq ,and get value of max_seq%max_ota_app_number
|
||||
//and boot a subtype (mask 0x0F) value is (max_seq - 1)%max_ota_app_number,so if want switch to run ota[x],can use next formulas.
|
||||
//for example, if s_ota_select[0].ota_seq = 4, s_ota_select[1].ota_seq = 5, and there are 8 ota application,
|
||||
//current running is (5-1)%8 = 4,running ota[4],so if we want to switch to run ota[7],
|
||||
//we should add s_ota_select[0].ota_seq (is 4) to 4 ,(8-1)%8=7,then it will boot ota[7]
|
||||
//if A=(B - C)%D
|
||||
//then B=(A + C)%D + D*n ,n= (0,1,2...)
|
||||
//so current ota app sub type id is x , dest bin subtype is y,total ota app count is n
|
||||
//seq will add (x + n*1 + 1 - seq)%n
|
||||
if (SUB_TYPE_ID(subtype) >= ota_app_count) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
ret = esp_partition_mmap(find_partition, 0, find_partition->size, SPI_FLASH_MMAP_DATA, &result, &ota_data_map);
|
||||
if (ret != ESP_OK) {
|
||||
result = NULL;
|
||||
return ret;
|
||||
} else {
|
||||
memcpy(&s_ota_select[0], result, sizeof(ota_select));
|
||||
memcpy(&s_ota_select[1], result + SPI_FLASH_SEC_SIZE, sizeof(ota_select));
|
||||
spi_flash_munmap(ota_data_map);
|
||||
}
|
||||
|
||||
if (ota_select_valid(&s_ota_select[0]) && ota_select_valid(&s_ota_select[1])) {
|
||||
seq = OTA_MAX(s_ota_select[0].ota_seq, s_ota_select[1].ota_seq);
|
||||
while (seq > (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count) {
|
||||
i++;
|
||||
}
|
||||
|
||||
if (s_ota_select[0].ota_seq >= s_ota_select[1].ota_seq) {
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 0, find_partition);
|
||||
} else {
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 1, find_partition);
|
||||
}
|
||||
|
||||
} else if (ota_select_valid(&s_ota_select[0])) {
|
||||
while (s_ota_select[0].ota_seq > (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count) {
|
||||
i++;
|
||||
}
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 1, find_partition);
|
||||
|
||||
} else if (ota_select_valid(&s_ota_select[1])) {
|
||||
while (s_ota_select[1].ota_seq > (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count) {
|
||||
i++;
|
||||
}
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 0, find_partition);
|
||||
|
||||
} else if (s_ota_select[0].ota_seq == 0xFFFFFFFF && s_ota_select[1].ota_seq == 0xFFFFFFFF) {
|
||||
return rewrite_ota_seq(SUB_TYPE_ID(subtype) + 1, 0, find_partition);
|
||||
|
||||
} else {
|
||||
return ESP_ERR_OTA_SELECT_INFO_INVALID;
|
||||
}
|
||||
|
||||
} else {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_set_boot_partition(const esp_partition_t *partition)
|
||||
{
|
||||
const esp_partition_t *find_partition = NULL;
|
||||
size_t image_size;
|
||||
if (partition == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECUREBOOTLOADER
|
||||
if (esp_image_basic_verify(partition->address, &image_size) != ESP_OK) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
ret = esp_secure_boot_verify_signature(partition->address, image_size);
|
||||
if (ret != ESP_OK) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
#endif
|
||||
// if set boot partition to factory bin ,just format ota info partition
|
||||
if (partition->type == ESP_PARTITION_TYPE_APP) {
|
||||
if (partition->subtype == ESP_PARTITION_SUBTYPE_APP_FACTORY) {
|
||||
find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
if (find_partition != NULL) {
|
||||
return esp_partition_erase_range(find_partition, find_partition->address, find_partition->size);
|
||||
} else {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
} else {
|
||||
// try to find this partition in flash,if not find it ,return error
|
||||
find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
if (find_partition != NULL) {
|
||||
return esp_rewrite_ota_data(partition->subtype);
|
||||
} else {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
const esp_partition_t *esp_ota_get_boot_partition(void)
|
||||
{
|
||||
esp_err_t ret;
|
||||
const esp_partition_t *find_partition = NULL;
|
||||
static spi_flash_mmap_memory_t ota_data_map;
|
||||
const void *result = NULL;
|
||||
uint16_t ota_app_count = 0;
|
||||
find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
|
||||
if (find_partition == NULL) {
|
||||
ESP_LOGE(TAG, "not found ota data");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = esp_partition_mmap(find_partition, 0, find_partition->size, SPI_FLASH_MMAP_DATA, &result, &ota_data_map);
|
||||
if (ret != ESP_OK) {
|
||||
spi_flash_munmap(ota_data_map);
|
||||
ESP_LOGE(TAG, "mmap ota data filed");
|
||||
return NULL;
|
||||
} else {
|
||||
memcpy(&s_ota_select[0], result, sizeof(ota_select));
|
||||
memcpy(&s_ota_select[1], result + 0x1000, sizeof(ota_select));
|
||||
spi_flash_munmap(ota_data_map);
|
||||
}
|
||||
ota_app_count = get_ota_partition_count();
|
||||
|
||||
ESP_LOGD(TAG, "found ota bin max = %d", ota_app_count);
|
||||
if (s_ota_select[0].ota_seq == 0xFFFFFFFF && s_ota_select[1].ota_seq == 0xFFFFFFFF) {
|
||||
ESP_LOGD(TAG, "finding factory bin......");
|
||||
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);
|
||||
} else if (ota_select_valid(&s_ota_select[0]) && ota_select_valid(&s_ota_select[1])) {
|
||||
ESP_LOGD(TAG, "finding ota_%d bin......", \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ((OTA_MAX(s_ota_select[0].ota_seq, s_ota_select[1].ota_seq) - 1) % ota_app_count));
|
||||
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ((OTA_MAX(s_ota_select[0].ota_seq, s_ota_select[1].ota_seq) - 1) % ota_app_count), NULL);
|
||||
} else if (ota_select_valid(&s_ota_select[0])) {
|
||||
ESP_LOGD(TAG, "finding ota_%d bin......", \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[0].ota_seq - 1) % ota_app_count);
|
||||
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[0].ota_seq - 1) % ota_app_count, NULL);
|
||||
|
||||
} else if (ota_select_valid(&s_ota_select[1])) {
|
||||
ESP_LOGD(TAG, "finding ota_%d bin......", \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[1].ota_seq - 1) % ota_app_count);
|
||||
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[1].ota_seq - 1) % ota_app_count, NULL);
|
||||
|
||||
} else {
|
||||
ESP_LOGE(TAG, "not found current bin");
|
||||
return NULL;
|
||||
}
|
||||
}
|
106
components/app_update/include/esp_ota_ops.h
Executable file
106
components/app_update/include/esp_ota_ops.h
Executable file
@ -0,0 +1,106 @@
|
||||
// Copyright 2015-2016 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.
|
||||
|
||||
#ifndef _OTA_OPS_H
|
||||
#define _OTA_OPS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_partition.h"
|
||||
#include "esp_spi_flash.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define OTA_SIZE_UNKNOWN 0xffffffff
|
||||
|
||||
#define ESP_ERR_OTA_BASE 0x1500 /*!< base error code for ota_ops api */
|
||||
#define ESP_ERR_OTA_PARTITION_CONFLICT (ESP_ERR_OTA_BASE + 0x01) /*!< want to write or erase current running partition */
|
||||
#define ESP_ERR_OTA_SELECT_INFO_INVALID (ESP_ERR_OTA_BASE + 0x02) /*!< ota data partition info is error */
|
||||
#define ESP_ERR_OTA_VALIDATE_FAILED (ESP_ERR_OTA_BASE + 0x03) /*!< validate ota image failed */
|
||||
|
||||
/**
|
||||
* @brief Opaque handle for application update obtained from app_ops.
|
||||
*/
|
||||
typedef uint32_t esp_ota_handle_t;
|
||||
|
||||
/**
|
||||
* @brief format input partition in flash to 0xFF as input image size,
|
||||
* if unkown image size ,pass 0x0 or 0xFFFFFFFF, it will erase all the
|
||||
* partition ,Otherwise, erase the required range
|
||||
*
|
||||
* @param partition Pointer to partition structure which need to be updated
|
||||
* Must be non-NULL.
|
||||
* @param image_size size of image need to be updated
|
||||
* @param out_handle handle which should be used for esp_ota_write or esp_ota_end call
|
||||
|
||||
* @return: ESP_OK if format ota image OK
|
||||
* ESP_ERR_OTA_PARTITION_CONFLICT operate current running bin
|
||||
* ESP_ERR_OTA_SELECT_INFO_INVALID ota bin select info invalid
|
||||
*/
|
||||
esp_err_t esp_ota_begin(const esp_partition_t* partition, size_t image_size, esp_ota_handle_t* out_handle);
|
||||
|
||||
/**
|
||||
* @brief Write data to input input partition
|
||||
*
|
||||
* @param handle Handle obtained from esp_ota_begin
|
||||
* @param data Pointer to data write to flash
|
||||
* @param size data size of recieved data
|
||||
*
|
||||
* @return: ESP_OK if write flash data OK
|
||||
* ESP_ERR_OTA_PARTITION_CONFLICT operate current running bin
|
||||
* ESP_ERR_OTA_SELECT_INFO_INVALID ota bin select info invalid
|
||||
*/
|
||||
esp_err_t esp_ota_write(esp_ota_handle_t handle, const void* data, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Finish the update and validate written data
|
||||
*
|
||||
* @param handle Handle obtained from esp_ota_begin
|
||||
*
|
||||
* @return: ESP_OK if validate ota image pass
|
||||
* ESP_ERR_OTA_VALIDATE_FAILED validate the ota image is invalid
|
||||
*/
|
||||
esp_err_t esp_ota_end(esp_ota_handle_t handle);
|
||||
|
||||
/**
|
||||
* @brief Set next boot partition, call system_restart() will switch to run it
|
||||
*
|
||||
* @note if you want switch to run a bin file
|
||||
* has never been checked before,please validate it's signature firstly
|
||||
*
|
||||
* @param partition Pointer to partition structure which need to boot
|
||||
*
|
||||
* @return: ESP_OK if set next boot partition OK
|
||||
* ESP_ERR_OTA_SELECT_INFO_INVALID ota bin select info invalid
|
||||
*/
|
||||
esp_err_t esp_ota_set_boot_partition(const esp_partition_t* partition);
|
||||
|
||||
/**
|
||||
* @brief Get partition info of current running image
|
||||
*
|
||||
* @return pointer to esp_partition_t structure, or NULL if no partition is found or
|
||||
* operate flash failed,This pointer is valid for the lifetime of the application.
|
||||
*/
|
||||
const esp_partition_t* esp_ota_get_boot_partition(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OTA_OPS_H */
|
@ -25,7 +25,6 @@
|
||||
typedef SHA_CTX sha_context;
|
||||
#else
|
||||
#include "hwcrypto/sha.h"
|
||||
typedef esp_sha_context sha_context;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
@ -42,7 +41,9 @@ extern const uint8_t signature_verification_key_end[] asm("_binary_signature_ver
|
||||
|
||||
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
|
||||
{
|
||||
sha_context sha;
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
SHA_CTX sha;
|
||||
#endif
|
||||
uint8_t digest[32];
|
||||
ptrdiff_t keylen;
|
||||
const uint8_t *data;
|
||||
@ -83,12 +84,8 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
|
||||
ets_sha_finish(&sha, SHA2_256, digest);
|
||||
ets_sha_disable();
|
||||
#else
|
||||
/* Use thread-safe esp-idf SHA layer */
|
||||
esp_sha256_init(&sha);
|
||||
esp_sha256_start(&sha, false);
|
||||
esp_sha256_update(&sha, data, length);
|
||||
esp_sha256_finish(&sha, digest);
|
||||
esp_sha256_free(&sha);
|
||||
/* Use thread-safe esp-idf SHA function */
|
||||
esp_sha(SHA2_256, data, length, digest);
|
||||
#endif
|
||||
|
||||
keylen = signature_verification_key_end - signature_verification_key_start;
|
||||
|
@ -115,7 +115,7 @@ static struct osi_funcs_t osi_funcs = {
|
||||
._mutex_create = mutex_create_wrapper,
|
||||
._mutex_lock = mutex_lock_wrapper,
|
||||
._mutex_unlock = mutex_unlock_wrapper,
|
||||
._read_efuse_mac = system_efuse_read_mac,
|
||||
._read_efuse_mac = esp_efuse_read_mac,
|
||||
};
|
||||
|
||||
static void bt_controller_task(void *pvParam)
|
||||
|
359
components/driver/include/driver/pcnt.h
Normal file
359
components/driver/include/driver/pcnt.h
Normal file
@ -0,0 +1,359 @@
|
||||
#ifndef __PCNT_H__
|
||||
#define __PCNT_H__
|
||||
|
||||
#include <esp_types.h>
|
||||
#include "esp_intr.h"
|
||||
#include "esp_err.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/pcnt_reg.h"
|
||||
#include "soc/pcnt_struct.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PCNT_PIN_NOT_USED (-1) /*!< Pin are not used */
|
||||
|
||||
typedef enum {
|
||||
PCNT_MODE_KEEP = 0, /*!< Control mode: won't change counter mode*/
|
||||
PCNT_MODE_REVERSE = 1, /*!< Control mode: invert counter mode(increase -> decrease, decrease -> increase);*/
|
||||
PCNT_MODE_DISABLE = 2, /*!< Control mode: Inhibit counter(counter value will not change in this condition)*/
|
||||
PCNT_MODE_MAX
|
||||
} pcnt_ctrl_mode_t;
|
||||
|
||||
typedef enum {
|
||||
PCNT_COUNT_DIS = 0, /*!< Counter mode: Decrease counter value*/
|
||||
PCNT_COUNT_INC = 1, /*!< Counter mode: Increase counter value*/
|
||||
PCNT_COUNT_DEC = 2, /*!< Counter mode: Inhibit counter(counter value will not change in this condition)*/
|
||||
PCNT_COUNT_MAX
|
||||
} pcnt_count_mode_t;
|
||||
|
||||
typedef enum {
|
||||
PCNT_UNIT_0 = 0, /*!< PCNT unit0 */
|
||||
PCNT_UNIT_1 = 1, /*!< PCNT unit1 */
|
||||
PCNT_UNIT_2 = 2, /*!< PCNT unit2 */
|
||||
PCNT_UNIT_3 = 3, /*!< PCNT unit3 */
|
||||
PCNT_UNIT_4 = 4, /*!< PCNT unit4 */
|
||||
PCNT_UNIT_5 = 5, /*!< PCNT unit5 */
|
||||
PCNT_UNIT_6 = 6, /*!< PCNT unit6 */
|
||||
PCNT_UNIT_7 = 7, /*!< PCNT unit7 */
|
||||
PCNT_UNIT_MAX,
|
||||
} pcnt_unit_t;
|
||||
|
||||
typedef enum{
|
||||
PCNT_CHANNEL_0 = 0x00, /*!< PCNT channel0 */
|
||||
PCNT_CHANNEL_1 = 0x01, /*!< PCNT channel1 */
|
||||
PCNT_CHANNEL_MAX,
|
||||
} pcnt_channel_t;
|
||||
|
||||
typedef enum {
|
||||
PCNT_EVT_L_LIM = 0, /*!< PCNT watch point event: Minimum counter value */
|
||||
PCNT_EVT_H_LIM = 1, /*!< PCNT watch point event: Maximum counter value*/
|
||||
PCNT_EVT_THRES_0 = 2, /*!< PCNT watch point event: threshold0 value event*/
|
||||
PCNT_EVT_THRES_1 = 3, /*!< PCNT watch point event: threshold1 value event*/
|
||||
PCNT_EVT_ZERO = 4, /*!< PCNT watch point event: counter value zero event*/
|
||||
PCNT_EVT_MAX
|
||||
} pcnt_evt_type_t;
|
||||
|
||||
/**
|
||||
* @brief Pulse Counter configure struct
|
||||
*/
|
||||
typedef struct {
|
||||
int pulse_gpio_num; /*!< Pulse input gpio_num, if you want to use gpio16, pulse_gpio_num = 16, a negative value will be ignored */
|
||||
int ctrl_gpio_num; /*!< Contol signal input gpio_num, a negative value will be ignored*/
|
||||
pcnt_ctrl_mode_t lctrl_mode; /*!< PCNT low control mode*/
|
||||
pcnt_ctrl_mode_t hctrl_mode; /*!< PCNT high control mode*/
|
||||
pcnt_count_mode_t pos_mode; /*!< PCNT positive edge count mode*/
|
||||
pcnt_count_mode_t neg_mode; /*!< PCNT negative edge count mode*/
|
||||
int16_t counter_h_lim; /*!< Maximum counter value */
|
||||
int16_t counter_l_lim; /*!< Minimum counter value */
|
||||
pcnt_unit_t unit; /*!< PCNT unit number */
|
||||
pcnt_channel_t channel; /*!< the PCNT channel */
|
||||
} pcnt_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configure Pulse Counter unit
|
||||
*
|
||||
* @param pcnt_config Pointer of Pulse Counter unit configure parameter
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t pcnt_unit_config(pcnt_config_t *pcnt_config);
|
||||
|
||||
/**
|
||||
* @brief Get pulse counter value
|
||||
*
|
||||
* @param pcnt_unit Pulse Counter unit number
|
||||
* @param count Pointer to accept counter value
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t pcnt_get_counter_value(pcnt_unit_t pcnt_unit, int16_t* count);
|
||||
|
||||
/**
|
||||
* @brief Pause PCNT counter of PCNT unit
|
||||
*
|
||||
* @param pcnt_unit PCNT unit number
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t pcnt_counter_pause(pcnt_unit_t pcnt_unit);
|
||||
|
||||
/**
|
||||
* @brief Resume counting for PCNT counter
|
||||
*
|
||||
* @param pcnt_unit PCNT unit number, select from pcnt_unit_t
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t pcnt_counter_resume(pcnt_unit_t pcnt_unit);
|
||||
|
||||
/**
|
||||
* @brief Clear and reset PCNT counter value to zero
|
||||
*
|
||||
* @param pcnt_unit PCNT unit number, select from pcnt_unit_t
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t pcnt_counter_clear(pcnt_unit_t pcnt_unit);
|
||||
|
||||
/**
|
||||
* @brief Enable PCNT interrupt for PCNT unit
|
||||
* @note
|
||||
* Each Pulse counter unit has five watch point events that share the same interrupt.
|
||||
* Configure events with pcnt_event_enable() and pcnt_event_disable()
|
||||
*
|
||||
* @param pcnt_unit PCNT unit number
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t pcnt_intr_enable(pcnt_unit_t pcnt_unit);
|
||||
|
||||
/**
|
||||
* @brief Disable PCNT interrupt for PCNT uint
|
||||
*
|
||||
* @param pcnt_unit PCNT unit number
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t pcnt_intr_disable(pcnt_unit_t pcnt_unit);
|
||||
|
||||
/**
|
||||
* @brief Enable PCNT event of PCNT unit
|
||||
*
|
||||
* @param unit PCNT unit number
|
||||
* @param evt_type Watch point event type.
|
||||
* All enabled events share the same interrupt (one interrupt per pulse counter unit).
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t pcnt_event_enable(pcnt_unit_t unit, pcnt_evt_type_t evt_type);
|
||||
|
||||
/**
|
||||
* @brief Disable PCNT event of PCNT unit
|
||||
*
|
||||
* @param unit PCNT unit number
|
||||
* @param evt_type Watch point event type.
|
||||
* All enabled events share the same interrupt (one interrupt per pulse counter unit).
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t pcnt_event_disable(pcnt_unit_t unit, pcnt_evt_type_t evt_type);
|
||||
|
||||
/**
|
||||
* @brief Set PCNT event value of PCNT unit
|
||||
*
|
||||
* @param unit PCNT unit number
|
||||
* @param evt_type Watch point event type.
|
||||
* All enabled events share the same interrupt (one interrupt per pulse counter unit).
|
||||
*
|
||||
* @param value Counter value for PCNT event
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t pcnt_set_event_value(pcnt_unit_t unit, pcnt_evt_type_t evt_type, int16_t value);
|
||||
|
||||
/**
|
||||
* @brief Get PCNT event value of PCNT unit
|
||||
*
|
||||
* @param unit PCNT unit number
|
||||
* @param evt_type Watch point event type.
|
||||
* All enabled events share the same interrupt (one interrupt per pulse counter unit).
|
||||
* @param value Pointer to accept counter value for PCNT event
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t pcnt_get_event_value(pcnt_unit_t unit, pcnt_evt_type_t evt_type, int16_t *value);
|
||||
|
||||
/**
|
||||
* @brief Register PCNT interrupt handler, the handler is an ISR.
|
||||
* The handler will be attached to the same CPU core that this function is running on.
|
||||
* @note
|
||||
* Users should know that which CPU is running and then pick a INUM that is not used by system.
|
||||
* We can find the information of INUM and interrupt level in soc.h.
|
||||
*
|
||||
* @param pcnt_intr_num PCNT interrupt number, check the info in soc.h, and please see the core-isa.h for more details
|
||||
* @param fn Interrupt handler function.
|
||||
* @note
|
||||
* Note that the handler function MUST be defined with attribution of "IRAM_ATTR".
|
||||
* @param arg Parameter for handler function
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Function pointer error.
|
||||
*/
|
||||
esp_err_t pcnt_isr_register(uint32_t pcnt_intr_num, void (*fn)(void*), void * arg);
|
||||
|
||||
/**
|
||||
* @brief Configure PCNT pulse signal input pin and control input pin
|
||||
*
|
||||
* @param unit PCNT unit number
|
||||
* @param channel PCNT channel number
|
||||
* @param pulse_io Pulse signal input GPIO
|
||||
* @note
|
||||
* Set to PCNT_PIN_NOT_USED if unused.
|
||||
* @param ctrl_io Control signal input GPIO
|
||||
* @note
|
||||
* Set to PCNT_PIN_NOT_USED if unused.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t pcnt_set_pin(pcnt_unit_t unit, pcnt_channel_t channel, int pulse_io, int ctrl_io);
|
||||
|
||||
/**
|
||||
* @brief Enable PCNT input filter
|
||||
*
|
||||
* @param unit PCNT unit number
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t pcnt_filter_enable(pcnt_unit_t unit);
|
||||
|
||||
/**
|
||||
* @brief Disable PCNT input filter
|
||||
*
|
||||
* @param unit PCNT unit number
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t pcnt_filter_disable(pcnt_unit_t unit);
|
||||
|
||||
/**
|
||||
* @brief Set PCNT filter value
|
||||
*
|
||||
* @param unit PCNT unit number
|
||||
* @param filter_val PCNT signal filter value, counter in APB_CLK cycles.
|
||||
* Any pulses lasting shorter than this will be ignored when the filter is enabled.
|
||||
* @note
|
||||
* filter_val is a 10-bit value, so the maximum filter_val should be limited to 1023.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t pcnt_set_filter_value(pcnt_unit_t unit, uint16_t filter_val);
|
||||
|
||||
/**
|
||||
* @brief Get PCNT filter value
|
||||
*
|
||||
* @param unit PCNT unit number
|
||||
* @param filter_val Pointer to accept PCNT filter value.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t pcnt_get_filter_value(pcnt_unit_t unit, uint16_t *filter_val);
|
||||
|
||||
/**
|
||||
* @brief Set PCNT counter mode
|
||||
*
|
||||
* @param unit PCNT unit number
|
||||
* @param channel PCNT channel number
|
||||
* @param pos_mode Counter mode when detecting positive edge
|
||||
* @param neg_mode Counter mode when detecting negative edge
|
||||
* @param hctrl_mode Counter mode when control signal is high level
|
||||
* @param lctrl_mode Counter mode when control signal is low level
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t pcnt_set_mode(pcnt_unit_t unit, pcnt_channel_t channel,
|
||||
pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode,
|
||||
pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode);
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup pcnt-examples
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* EXAMPLE OF PCNT CONFIGURATION
|
||||
* ==============================
|
||||
* @code{c}
|
||||
* //1. Config PCNT unit
|
||||
* pcnt_config_t pcnt_config = {
|
||||
* .pulse_gpio_num = 4, //set gpio4 as pulse input gpio
|
||||
* .ctrl_gpio_num = 5, //set gpio5 as control gpio
|
||||
* .channel = PCNT_CHANNEL_0, //use unit 0 channel 0
|
||||
* .lctrl_mode = PCNT_MODE_REVERSE, //when control signal is low ,reverse the primary counter mode(inc->dec/dec->inc)
|
||||
* .hctrl_mode = PCNT_MODE_KEEP, //when control signal is high,keep the primary counter mode
|
||||
* .pos_mode = PCNT_COUNT_INC, //increment the counter
|
||||
* .neg_mode = PCNT_COUNT_DIS, //keep the counter value
|
||||
* .counter_h_lim = 10,
|
||||
* .counter_l_lim = -10,
|
||||
* };
|
||||
* pcnt_unit_config(&pcnt_config); //init unit
|
||||
* @endcode
|
||||
*
|
||||
* EXAMPLE OF PCNT EVENT SETTING
|
||||
* ==============================
|
||||
* @code{c}
|
||||
* //2. Configure PCNT watchpoint event.
|
||||
* pcnt_set_event_value(PCNT_UNIT_0, PCNT_EVT_THRES_1, 5); //set thres1 value
|
||||
* pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_THRES_1); //enable thres1 event
|
||||
* @endcode
|
||||
*
|
||||
* For more examples please refer to PCNT example code in IDF_PATH/examples
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
@ -40,6 +40,7 @@ typedef enum {
|
||||
PERIPH_UHCI0_MODULE,
|
||||
PERIPH_UHCI1_MODULE,
|
||||
PERIPH_RMT_MODULE,
|
||||
PERIPH_PCNT_MODULE,
|
||||
} periph_module_t;
|
||||
|
||||
/**
|
||||
|
349
components/driver/include/driver/timer.h
Normal file
349
components/driver/include/driver/timer.h
Normal file
@ -0,0 +1,349 @@
|
||||
// Copyright 2010-2016 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.
|
||||
|
||||
#ifndef _DRIVER_TIMER_H_
|
||||
#define _DRIVER_TIMER_H_
|
||||
#include "esp_err.h"
|
||||
#include "esp_attr.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define TIMER_BASE_CLK (APB_CLK_FREQ)
|
||||
/**
|
||||
* @brief Selects a Timer-Group out of 2 available groups
|
||||
*/
|
||||
typedef enum {
|
||||
TIMER_GROUP_0 = 0, /*!<Hw timer group 0*/
|
||||
TIMER_GROUP_1 = 1, /*!<Hw timer group 1*/
|
||||
TIMER_GROUP_MAX,
|
||||
} timer_group_t;
|
||||
|
||||
/**
|
||||
* @brief Select a hardware timer from timer groups
|
||||
*/
|
||||
typedef enum {
|
||||
TIMER_0 = 0, /*!<Select timer0 of GROUPx*/
|
||||
TIMER_1 = 1, /*!<Select timer1 of GROUPx*/
|
||||
TIMER_MAX,
|
||||
} timer_idx_t;
|
||||
|
||||
/**
|
||||
* @brief Decides the direction of counter
|
||||
*/
|
||||
typedef enum {
|
||||
TIMER_COUNT_DOWN = 0, /*!< Descending Count from cnt.high|cnt.low*/
|
||||
TIMER_COUNT_UP = 1, /*!< Ascending Count from Zero*/
|
||||
TIMER_COUNT_MAX
|
||||
} timer_count_dir_t;
|
||||
|
||||
/**
|
||||
* @brief Decides whether timer is on or paused
|
||||
*/
|
||||
typedef enum {
|
||||
TIMER_PAUSE = 0, /*!<Pause timer counter*/
|
||||
TIMER_START = 1, /*!<Start timer counter*/
|
||||
} timer_start_t;
|
||||
|
||||
/**
|
||||
* @brief Decides whether to enable alarm mode
|
||||
*/
|
||||
typedef enum {
|
||||
TIMER_ALARM_DIS = 0, /*!< Disable timer alarm*/
|
||||
TIMER_ALARM_EN = 1, /*!< Enable timer alarm*/
|
||||
TIMER_ALARM_MAX
|
||||
} timer_alarm_t;
|
||||
|
||||
/**
|
||||
* @brief Select interrupt type if running in alarm mode.
|
||||
*/
|
||||
typedef enum {
|
||||
TIMER_INTR_LEVEL = 0, /*!< Interrupt mode: level mode*/
|
||||
//TIMER_INTR_EDGE = 1, /*!< Interrupt mode: edge mode, Not supported Now*/
|
||||
TIMER_INTR_MAX
|
||||
} timer_intr_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Select if Alarm needs to be loaded by software or automatically reload by hardware.
|
||||
*/
|
||||
typedef enum {
|
||||
TIMER_AUTORELOAD_DIS = 0, /*!< Disable auto-reload: hardware will not load counter value after an alarm event*/
|
||||
TIMER_AUTORELOAD_EN = 1, /*!< Enable auto-reload: hardware will load counter value after an alarm event*/
|
||||
TIMER_AUTORELOAD_MAX,
|
||||
} timer_autoreload_t;
|
||||
|
||||
/**
|
||||
* @brief timer configure struct
|
||||
*/
|
||||
typedef struct {
|
||||
bool alarm_en; /*!< Timer alarm enable */
|
||||
bool counter_en; /*!< Counter enable */
|
||||
timer_count_dir_t counter_dir; /*!< Counter direction */
|
||||
timer_intr_mode_t intr_type; /*!< Interrupt mode */
|
||||
bool auto_reload; /*!< Timer auto-reload */
|
||||
uint16_t divider; /*!< Counter clock divider*/
|
||||
} timer_config_t;
|
||||
|
||||
/**
|
||||
* @brief Read the counter value of hardware timer.
|
||||
*
|
||||
* @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
|
||||
* @param timer_val Pointer to accept timer counter value.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_get_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t* timer_val);
|
||||
|
||||
/**
|
||||
* @brief Read the counter value of hardware timer, in unit of a given scale.
|
||||
*
|
||||
* @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
|
||||
* @param time Pointer, type of double*, to accept timer counter value, in seconds.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_get_counter_time_sec(timer_group_t group_num, timer_idx_t timer_num, double* time);
|
||||
|
||||
/**
|
||||
* @brief Set counter value to hardware timer.
|
||||
*
|
||||
* @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
|
||||
* @param load_val Counter value to write to the hardware timer.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_set_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t load_val);
|
||||
|
||||
/**
|
||||
* @brief Start the counter of hardware timer.
|
||||
*
|
||||
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_start(timer_group_t group_num, timer_idx_t timer_num);
|
||||
|
||||
/**
|
||||
* @brief Pause the counter of hardware timer.
|
||||
*
|
||||
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_pause(timer_group_t group_num, timer_idx_t timer_num);
|
||||
|
||||
/**
|
||||
* @brief Set counting mode for hardware timer.
|
||||
*
|
||||
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
|
||||
* @param counter_dir Counting direction of timer, count-up or count-down
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_set_counter_mode(timer_group_t group_num, timer_idx_t timer_num, timer_count_dir_t counter_dir);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable counter reload function when alarm event occurs.
|
||||
*
|
||||
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
|
||||
* @param reload Counter reload mode.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_set_auto_reload(timer_group_t group_num, timer_idx_t timer_num, timer_autoreload_t reload);
|
||||
|
||||
/**
|
||||
* @brief Set hardware timer source clock divider. Timer groups clock are divider from APB clock.
|
||||
*
|
||||
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
|
||||
* @param divider Timer clock divider value.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_set_divider(timer_group_t group_num, timer_idx_t timer_num, uint16_t divider);
|
||||
|
||||
/**
|
||||
* @brief Set timer alarm value.
|
||||
*
|
||||
* @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
|
||||
* @param alarm_value A 64-bit value to set the alarm value.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_set_alarm_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_value);
|
||||
|
||||
/**
|
||||
* @brief Get timer alarm value.
|
||||
*
|
||||
* @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
|
||||
* @param alarm_value Pointer of A 64-bit value to accept the alarm value.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_get_alarm_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t* alarm_value);
|
||||
|
||||
/**
|
||||
* @brief Get timer alarm value.
|
||||
*
|
||||
* @param group_num Timer group, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
|
||||
* @param alarm_en To enable or disable timer alarm function.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_alarm_t alarm_en);
|
||||
|
||||
|
||||
/**
|
||||
* @brief register Timer interrupt handler, the handler is an ISR.
|
||||
* The handler will be attached to the same CPU core that this function is running on.
|
||||
* @note
|
||||
* Users should know that which CPU is running and then pick a INUM that is not used by system.
|
||||
* We can find the information of INUM and interrupt level in soc.h.
|
||||
*
|
||||
* @param group_num Timer group number
|
||||
* @param timer_num Timer index of timer group
|
||||
* @param timer_intr_num TIMER interrupt number, check the info in soc.h, and please see the core-isa.h for more details
|
||||
* @param intr_type Timer interrupt type
|
||||
* @param fn Interrupt handler function.
|
||||
* @note
|
||||
* Code inside the handler function can only call functions in IRAM, so cannot call other timer APIs.
|
||||
* Use direct register access to access timers from inside the ISR.
|
||||
*
|
||||
* @param arg Parameter for handler function
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Function pointer error.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num, int timer_intr_num, timer_intr_mode_t intr_type, void (*fn)(void*), void * arg);
|
||||
|
||||
/** @brief Initializes and configure the timer.
|
||||
*
|
||||
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
|
||||
* @param config Pointer to timer initialization parameters.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, timer_config_t* config);
|
||||
|
||||
/** @brief Get timer configure value.
|
||||
*
|
||||
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1]
|
||||
* @param config Pointer of struct to accept timer parameters.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_get_config(timer_group_t group_num, timer_idx_t timer_num, timer_config_t *config);
|
||||
|
||||
/** @brief Enable timer group interrupt, by enable mask
|
||||
*
|
||||
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param en_mask Timer interrupt enable mask.
|
||||
* Use TIMG_T0_INT_ENA_M to enable t0 interrupt
|
||||
* Use TIMG_T1_INT_ENA_M to enable t1 interrupt
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_group_intr_enable(timer_group_t group_num, uint32_t en_mask);
|
||||
|
||||
/** @brief Disable timer group interrupt, by disable mask
|
||||
*
|
||||
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param disable_mask Timer interrupt disable mask.
|
||||
* Use TIMG_T0_INT_ENA_M to disable t0 interrupt
|
||||
* Use TIMG_T1_INT_ENA_M to disable t1 interrupt
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_group_intr_disable(timer_group_t group_num, uint32_t disable_mask);
|
||||
|
||||
/** @brief Enable timer interrupt
|
||||
*
|
||||
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_enable_intr(timer_group_t group_num, timer_idx_t timer_num);
|
||||
|
||||
/** @brief Disable timer interrupt
|
||||
*
|
||||
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_disable_intr(timer_group_t group_num, timer_idx_t timer_num);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TIMER_H_ */
|
@ -167,25 +167,25 @@ esp_err_t uart_get_word_length(uart_port_t uart_num, uart_word_length_t* data_bi
|
||||
* @brief Set UART stop bits.
|
||||
*
|
||||
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
|
||||
* @param bit_num UART stop bits
|
||||
* @param stop_bits UART stop bits
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_FAIL Fail
|
||||
*/
|
||||
esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t bit_num);
|
||||
esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bits);
|
||||
|
||||
/**
|
||||
* @brief Set UART stop bits.
|
||||
*
|
||||
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
|
||||
* @param stop_bit Pointer to accept value of UART stop bits.
|
||||
* @param stop_bits Pointer to accept value of UART stop bits.
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success, result will be put in (*stop_bit)
|
||||
*/
|
||||
esp_err_t uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t* stop_bit);
|
||||
esp_err_t uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t* stop_bits);
|
||||
|
||||
/**
|
||||
* @brief Set UART parity.
|
||||
@ -216,13 +216,13 @@ esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode);
|
||||
* @brief Set UART baud rate.
|
||||
*
|
||||
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
|
||||
* @param baud_rate UART baud-rate.
|
||||
* @param baudrate UART baud rate.
|
||||
*
|
||||
* @return
|
||||
* - ESP_FAIL Parameter error
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate);
|
||||
esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baudrate);
|
||||
|
||||
/**
|
||||
* @brief Get UART bit-rate.
|
||||
@ -241,7 +241,7 @@ esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t* baudrate);
|
||||
* @brief Set UART line inverse mode
|
||||
*
|
||||
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
|
||||
* @param inverse_mask Choose the wires that need to be inversed.
|
||||
* @param inverse_mask Choose the wires that need to be inverted.
|
||||
* Inverse_mask should be chosen from UART_INVERSE_RXD/UART_INVERSE_TXD/UART_INVERSE_RTS/UART_INVERSE_CTS, combine with OR operation.
|
||||
*
|
||||
* @return
|
||||
|
@ -137,29 +137,32 @@ esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(timer_num > LEDC_TIMER_3) {
|
||||
ESP_LOGE(LEDC_TAG, "Time Select %u", timer_num);
|
||||
ESP_LOGE(LEDC_TAG, "invalid timer #%u", timer_num);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_err_t ret = ESP_OK;
|
||||
uint32_t precision = (0x1 << bit_num); //2**depth
|
||||
uint64_t div_param = ((uint64_t) LEDC_APB_CLK_HZ << 8) / freq_hz / precision; //8bit fragment
|
||||
int timer_clk_src;
|
||||
/*Fail ,because the div_num overflow or too small*/
|
||||
if(div_param <= 256 || div_param > LEDC_DIV_NUM_HSTIMER0_V) { //REF TICK
|
||||
/*Selet the reference tick*/
|
||||
uint32_t precision = (0x1 << bit_num); // 2**depth
|
||||
// Try calculating divisor based on LEDC_APB_CLK
|
||||
ledc_clk_src_t timer_clk_src = LEDC_APB_CLK;
|
||||
// div_param is a Q10.8 fixed point value
|
||||
uint64_t div_param = ((uint64_t) LEDC_APB_CLK_HZ << 8) / freq_hz / precision;
|
||||
if (div_param < 256) {
|
||||
// divisor is too low
|
||||
ESP_LOGE(LEDC_TAG, "requested frequency and bit depth can not be achieved, try reducing freq_hz or bit_num. div_param=%d", (uint32_t) div_param);
|
||||
ret = ESP_FAIL;
|
||||
}
|
||||
if (div_param > LEDC_DIV_NUM_HSTIMER0_V) {
|
||||
// APB_CLK results in divisor which too high. Try using REF_TICK as clock source.
|
||||
timer_clk_src = LEDC_REF_TICK;
|
||||
div_param = ((uint64_t) LEDC_REF_CLK_HZ << 8) / freq_hz / precision;
|
||||
if(div_param <= 256 || div_param > LEDC_DIV_NUM_HSTIMER0_V) {
|
||||
ESP_LOGE(LEDC_TAG, "div param err,div_param=%u", (uint32_t)div_param);
|
||||
if(div_param < 256 || div_param > LEDC_DIV_NUM_HSTIMER0_V) {
|
||||
ESP_LOGE(LEDC_TAG, "requested frequency and bit depth can not be achieved, try increasing freq_hz or bit_num. div_param=%d", (uint32_t) div_param);
|
||||
ret = ESP_FAIL;
|
||||
}
|
||||
timer_clk_src = LEDC_REF_TICK;
|
||||
} else { //APB TICK
|
||||
timer_clk_src = LEDC_APB_CLK;
|
||||
}
|
||||
/*set timer parameters*/
|
||||
/*timer settings decide the clk of counter and the period of PWM*/
|
||||
// set timer parameters
|
||||
ledc_timer_set(speed_mode, timer_num, div_param, bit_num, timer_clk_src);
|
||||
/* reset timer.*/
|
||||
// reset timer
|
||||
ledc_timer_rst(speed_mode, timer_num);
|
||||
return ret;
|
||||
}
|
||||
@ -174,7 +177,8 @@ esp_err_t ledc_set_pin(int gpio_num, ledc_mode_t speed_mode, ledc_channel_t ledc
|
||||
if(speed_mode == LEDC_HIGH_SPEED_MODE) {
|
||||
gpio_matrix_out(gpio_num, LEDC_HS_SIG_OUT0_IDX + ledc_channel, 0, 0);
|
||||
} else {
|
||||
|
||||
ESP_LOGE(LEDC_TAG, "low speed mode is not implemented");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -191,6 +195,7 @@ esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf)
|
||||
LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "ledc mode error", ESP_ERR_INVALID_ARG);
|
||||
LEDC_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "ledc GPIO output number error", ESP_ERR_INVALID_ARG);
|
||||
LEDC_CHECK(timer_select <= LEDC_TIMER_3, "ledc timer error", ESP_ERR_INVALID_ARG);
|
||||
periph_module_enable(PERIPH_LEDC_MODULE);
|
||||
esp_err_t ret = ESP_OK;
|
||||
/*set channel parameters*/
|
||||
/* channel parameters decide how the waveform looks like in one period*/
|
||||
|
278
components/driver/pcnt.c
Normal file
278
components/driver/pcnt.c
Normal file
@ -0,0 +1,278 @@
|
||||
// Copyright 2015-2016 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 "esp_log.h"
|
||||
#include "driver/pcnt.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
|
||||
#define PCNT_CHANNEL_ERR_STR "PCNT CHANNEL ERROR"
|
||||
#define PCNT_UNIT_ERR_STR "PCNT UNIT ERROR"
|
||||
#define PCNT_GPIO_ERR_STR "PCNT GPIO NUM ERROR"
|
||||
#define PCNT_ADDRESS_ERR_STR "PCNT ADDRESS ERROR"
|
||||
#define PCNT_PARAM_ERR_STR "PCNT PARAM ERROR"
|
||||
#define PCNT_COUNT_MODE_ERR_STR "PCNT COUNTER MODE ERROR"
|
||||
#define PCNT_CTRL_MODE_ERR_STR "PCNT CTRL MODE ERROR"
|
||||
#define PCNT_EVT_TYPE_ERR_STR "PCNT value type error"
|
||||
#define PCNT_CHECK(a,str,ret_val) if(!(a)) { \
|
||||
ESP_LOGE(PCNT_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
|
||||
return (ret_val); \
|
||||
}
|
||||
|
||||
static const char* PCNT_TAG = "PCNT";
|
||||
static portMUX_TYPE pcnt_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
#define PCNT_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux)
|
||||
#define PCNT_EXIT_CRITICAL(mux) portEXIT_CRITICAL(mux)
|
||||
#define PCNT_ENTER_CRITICAL_ISR(mux) portENTER_CRITICAL_ISR(mux)
|
||||
#define PCNT_EXIT_CRITICAL_ISR(mux) portEXIT_CRITICAL_ISR(mux)
|
||||
|
||||
esp_err_t pcnt_unit_config(pcnt_config_t *pcnt_config)
|
||||
{
|
||||
uint8_t unit = pcnt_config->channel;
|
||||
uint8_t channel = pcnt_config->unit;
|
||||
int input_io = pcnt_config->pulse_gpio_num;
|
||||
int ctrl_io = pcnt_config->ctrl_gpio_num;
|
||||
|
||||
PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK(channel < PCNT_CHANNEL_MAX, PCNT_CHANNEL_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK(input_io < 0 || (GPIO_IS_VALID_GPIO(input_io) && (input_io != ctrl_io)), "PCNT pluse input io error", ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK(ctrl_io < 0 || GPIO_IS_VALID_GPIO(ctrl_io), "PCNT ctrl io error", ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK((pcnt_config->pos_mode < PCNT_COUNT_MAX) && (pcnt_config->neg_mode < PCNT_COUNT_MAX), PCNT_COUNT_MODE_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK((pcnt_config->hctrl_mode < PCNT_MODE_MAX) && (pcnt_config->lctrl_mode < PCNT_MODE_MAX), PCNT_CTRL_MODE_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
/*Enalbe hardware module*/
|
||||
periph_module_enable(PERIPH_PCNT_MODULE);
|
||||
/*Set counter range*/
|
||||
pcnt_set_event_value(unit, PCNT_EVT_H_LIM, pcnt_config->counter_h_lim);
|
||||
pcnt_set_event_value(unit, PCNT_EVT_L_LIM, pcnt_config->counter_l_lim);
|
||||
/*Default value after reboot is positive, we disable these events like others*/
|
||||
pcnt_event_disable(unit, PCNT_EVT_H_LIM);
|
||||
pcnt_event_disable(unit, PCNT_EVT_L_LIM);
|
||||
pcnt_event_disable(unit, PCNT_EVT_ZERO);
|
||||
pcnt_filter_disable(unit);
|
||||
/*set pulse input and control mode*/
|
||||
pcnt_set_mode(unit, channel, pcnt_config->pos_mode, pcnt_config->neg_mode, pcnt_config->hctrl_mode, pcnt_config->lctrl_mode);
|
||||
/*Set pulse input and control pins*/
|
||||
pcnt_set_pin(unit, channel, input_io, ctrl_io);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t pcnt_set_mode(pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode)
|
||||
{
|
||||
PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK(channel < PCNT_CHANNEL_MAX, PCNT_CHANNEL_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK((pos_mode < PCNT_COUNT_MAX) && (neg_mode < PCNT_COUNT_MAX), PCNT_COUNT_MODE_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK((hctrl_mode < PCNT_MODE_MAX) && (lctrl_mode < PCNT_MODE_MAX), PCNT_CTRL_MODE_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
|
||||
if(channel == 0) {
|
||||
PCNT.conf_unit[unit].conf0.ch0_pos_mode = pos_mode;
|
||||
PCNT.conf_unit[unit].conf0.ch0_neg_mode = neg_mode;
|
||||
PCNT.conf_unit[unit].conf0.ch0_hctrl_mode = hctrl_mode;
|
||||
PCNT.conf_unit[unit].conf0.ch0_lctrl_mode = lctrl_mode;
|
||||
} else {
|
||||
PCNT.conf_unit[unit].conf0.ch1_pos_mode = pos_mode;
|
||||
PCNT.conf_unit[unit].conf0.ch1_neg_mode = neg_mode;
|
||||
PCNT.conf_unit[unit].conf0.ch1_hctrl_mode = hctrl_mode;
|
||||
PCNT.conf_unit[unit].conf0.ch1_lctrl_mode = lctrl_mode;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t pcnt_set_pin(pcnt_unit_t unit, pcnt_channel_t channel, int pulse_io, int ctrl_io)
|
||||
{
|
||||
PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK(channel < PCNT_CHANNEL_MAX, PCNT_CHANNEL_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK(GPIO_IS_VALID_GPIO(pulse_io) || pulse_io < 0, PCNT_GPIO_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK(GPIO_IS_VALID_GPIO(ctrl_io) || ctrl_io < 0, PCNT_GPIO_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
int input_sig_index = (channel == 0 ? PCNT_SIG_CH0_IN0_IDX + 4 * unit : PCNT_SIG_CH1_IN0_IDX + 4 * unit);
|
||||
int ctrl_sig_index = (channel == 0 ? PCNT_CTRL_CH0_IN0_IDX + 4 * unit : PCNT_CTRL_CH1_IN0_IDX + 4 * unit);
|
||||
if(pulse_io >= 0) {
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[pulse_io], PIN_FUNC_GPIO);
|
||||
gpio_set_direction(pulse_io, GPIO_MODE_INPUT);
|
||||
gpio_set_pull_mode(pulse_io, GPIO_PULLUP_ONLY);
|
||||
gpio_matrix_in(pulse_io, input_sig_index, 0);
|
||||
}
|
||||
if(ctrl_io >= 0) {
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[ctrl_io], PIN_FUNC_GPIO);
|
||||
gpio_set_direction(ctrl_io, GPIO_MODE_INPUT);
|
||||
gpio_set_pull_mode(ctrl_io, GPIO_PULLUP_ONLY);
|
||||
gpio_matrix_in(ctrl_io, ctrl_sig_index, 0);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t pcnt_get_counter_value(pcnt_unit_t pcnt_unit, int16_t* count)
|
||||
{
|
||||
PCNT_CHECK(pcnt_unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK(count != NULL, PCNT_ADDRESS_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
*count = (int16_t) PCNT.cnt_unit[pcnt_unit].cnt_val;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t pcnt_counter_pause(pcnt_unit_t pcnt_unit)
|
||||
{
|
||||
PCNT_CHECK(pcnt_unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_ENTER_CRITICAL(&pcnt_spinlock);
|
||||
PCNT.ctrl.val |= BIT(PCNT_CNT_PAUSE_U0_S + (pcnt_unit * 2));
|
||||
PCNT_EXIT_CRITICAL(&pcnt_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t pcnt_counter_resume(pcnt_unit_t pcnt_unit)
|
||||
{
|
||||
PCNT_CHECK(pcnt_unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_ENTER_CRITICAL(&pcnt_spinlock);
|
||||
PCNT.ctrl.val &= (~(BIT(PCNT_CNT_PAUSE_U0_S + (pcnt_unit * 2))));
|
||||
PCNT_EXIT_CRITICAL(&pcnt_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t pcnt_counter_clear(pcnt_unit_t pcnt_unit)
|
||||
{
|
||||
PCNT_CHECK(pcnt_unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_ENTER_CRITICAL(&pcnt_spinlock);
|
||||
PCNT.ctrl.val &= (~(BIT(PCNT_PLUS_CNT_RST_U0_S + (pcnt_unit * 2))));
|
||||
PCNT_EXIT_CRITICAL(&pcnt_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t pcnt_intr_enable(pcnt_unit_t pcnt_unit)
|
||||
{
|
||||
PCNT_CHECK(pcnt_unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_ENTER_CRITICAL(&pcnt_spinlock);
|
||||
PCNT.int_ena.val |= BIT(PCNT_CNT_THR_EVENT_U0_INT_ENA_S + pcnt_unit);
|
||||
PCNT_EXIT_CRITICAL(&pcnt_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t pcnt_intr_disable(pcnt_unit_t pcnt_unit)
|
||||
{
|
||||
PCNT_CHECK(pcnt_unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_ENTER_CRITICAL(&pcnt_spinlock);
|
||||
PCNT.int_ena.val &= (~(BIT(PCNT_CNT_THR_EVENT_U0_INT_ENA_S + pcnt_unit)));
|
||||
PCNT_EXIT_CRITICAL(&pcnt_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t pcnt_event_enable(pcnt_unit_t unit, pcnt_evt_type_t evt_type)
|
||||
{
|
||||
PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK(evt_type < PCNT_EVT_MAX, PCNT_EVT_TYPE_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
if(evt_type == PCNT_EVT_L_LIM) {
|
||||
PCNT.conf_unit[unit].conf0.thr_l_lim_en = 1;
|
||||
} else if(evt_type == PCNT_EVT_H_LIM) {
|
||||
PCNT.conf_unit[unit].conf0.thr_h_lim_en = 1;
|
||||
} else if(evt_type == PCNT_EVT_THRES_0) {
|
||||
PCNT.conf_unit[unit].conf0.thr_thres0_en = 1;
|
||||
} else if(evt_type == PCNT_EVT_THRES_1) {
|
||||
PCNT.conf_unit[unit].conf0.thr_thres1_en = 1;
|
||||
} else if(evt_type == PCNT_EVT_ZERO) {
|
||||
PCNT.conf_unit[unit].conf0.thr_zero_en = 1;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t pcnt_event_disable(pcnt_unit_t unit, pcnt_evt_type_t evt_type)
|
||||
{
|
||||
PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK(evt_type < PCNT_EVT_MAX, PCNT_EVT_TYPE_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
if(evt_type == PCNT_EVT_L_LIM) {
|
||||
PCNT.conf_unit[unit].conf0.thr_l_lim_en = 0;
|
||||
} else if(evt_type == PCNT_EVT_H_LIM) {
|
||||
PCNT.conf_unit[unit].conf0.thr_h_lim_en = 0;
|
||||
} else if(evt_type == PCNT_EVT_THRES_0) {
|
||||
PCNT.conf_unit[unit].conf0.thr_thres0_en = 0;
|
||||
} else if(evt_type == PCNT_EVT_THRES_1) {
|
||||
PCNT.conf_unit[unit].conf0.thr_thres1_en = 0;
|
||||
} else if(evt_type == PCNT_EVT_ZERO) {
|
||||
PCNT.conf_unit[unit].conf0.thr_zero_en = 0;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t pcnt_set_event_value(pcnt_unit_t unit, pcnt_evt_type_t evt_type, int16_t value)
|
||||
{
|
||||
PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK(evt_type < PCNT_EVT_MAX, PCNT_EVT_TYPE_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
if(evt_type == PCNT_EVT_L_LIM) {
|
||||
PCNT.conf_unit[unit].conf2.cnt_l_lim = value;
|
||||
} else if(evt_type == PCNT_EVT_H_LIM) {
|
||||
PCNT.conf_unit[unit].conf2.cnt_h_lim = value;
|
||||
} else if(evt_type == PCNT_EVT_THRES_0) {
|
||||
PCNT.conf_unit[unit].conf1.cnt_thres0 = value;
|
||||
} else if(evt_type == PCNT_EVT_THRES_1) {
|
||||
PCNT.conf_unit[unit].conf1.cnt_thres1 = value;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t pcnt_get_event_value(pcnt_unit_t unit, pcnt_evt_type_t evt_type, int16_t *value)
|
||||
{
|
||||
PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK(evt_type < PCNT_EVT_MAX, PCNT_EVT_TYPE_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK(value != NULL, PCNT_ADDRESS_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
|
||||
if(evt_type == PCNT_EVT_L_LIM) {
|
||||
*value = (int16_t) PCNT.conf_unit[unit].conf2.cnt_l_lim;
|
||||
} else if(evt_type == PCNT_EVT_H_LIM) {
|
||||
*value = (int16_t) PCNT.conf_unit[unit].conf2.cnt_h_lim;
|
||||
} else if(evt_type == PCNT_EVT_THRES_0) {
|
||||
*value = (int16_t) PCNT.conf_unit[unit].conf1.cnt_thres0;
|
||||
} else if(evt_type == PCNT_EVT_THRES_1) {
|
||||
*value = (int16_t) PCNT.conf_unit[unit].conf1.cnt_thres1;
|
||||
} else {
|
||||
*value = 0;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t pcnt_set_filter_value(pcnt_unit_t unit, uint16_t filter_val)
|
||||
{
|
||||
PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK(filter_val < 1024, PCNT_PARAM_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT.conf_unit[unit].conf0.filter_thres = filter_val;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t pcnt_get_filter_value(pcnt_unit_t unit, uint16_t *filter_val)
|
||||
{
|
||||
PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT_CHECK(filter_val != NULL, PCNT_ADDRESS_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
|
||||
*filter_val = PCNT.conf_unit[unit].conf0.filter_thres;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t pcnt_filter_enable(pcnt_unit_t unit)
|
||||
{
|
||||
PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT.conf_unit[unit].conf0.filter_en = 1;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t pcnt_filter_disable(pcnt_unit_t unit)
|
||||
{
|
||||
PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
PCNT.conf_unit[unit].conf0.filter_en = 0;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t pcnt_isr_register(uint32_t pcnt_intr_num, void (*fun)(void*), void * arg)
|
||||
{
|
||||
PCNT_CHECK(fun != NULL, PCNT_ADDRESS_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_INTR_DISABLE(pcnt_intr_num);
|
||||
intr_matrix_set(xPortGetCoreID(), ETS_PCNT_INTR_SOURCE, pcnt_intr_num);
|
||||
xt_set_interrupt_handler(pcnt_intr_num, fun, arg);
|
||||
ESP_INTR_ENABLE(pcnt_intr_num);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -93,6 +93,10 @@ void periph_module_enable(periph_module_t periph)
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UHCI1_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UHCI1_RST);
|
||||
break;
|
||||
case PERIPH_PCNT_MODULE:
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -103,6 +107,10 @@ void periph_module_disable(periph_module_t periph)
|
||||
{
|
||||
portENTER_CRITICAL(&periph_spinlock);
|
||||
switch(periph) {
|
||||
case PERIPH_RMT_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_RMT_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_RMT_RST);
|
||||
break;
|
||||
case PERIPH_LEDC_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_LEDC_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_LEDC_RST);
|
||||
@ -167,6 +175,10 @@ void periph_module_disable(periph_module_t periph)
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UHCI1_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UHCI1_RST);
|
||||
break;
|
||||
case PERIPH_PCNT_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
275
components/driver/timer.c
Normal file
275
components/driver/timer.c
Normal file
@ -0,0 +1,275 @@
|
||||
// Copyright 2015-2016 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 "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_intr.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "driver/timer.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
|
||||
static const char* TIMER_TAG = "TIMER_GROUP";
|
||||
#define TIMER_CHECK(a, str, ret_val) if (!(a)) { \
|
||||
ESP_LOGE(TIMER_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
|
||||
return (ret_val); \
|
||||
}
|
||||
#define TIMER_GROUP_NUM_ERROR "TIMER GROUP NUM ERROR"
|
||||
#define TIMER_NUM_ERROR "HW TIMER NUM ERROR"
|
||||
#define TIMER_PARAM_ADDR_ERROR "HW TIMER PARAM ADDR ERROR"
|
||||
#define TIMER_COUNT_DIR_ERROR "HW TIMER COUNTER DIR ERROR"
|
||||
#define TIMER_AUTORELOAD_ERROR "HW TIMER AUTORELOAD ERROR"
|
||||
#define TIMER_SCALE_ERROR "HW TIMER SCALE ERROR"
|
||||
#define TIMER_ALARM_ERROR "HW TIMER ALARM ERROR"
|
||||
static timg_dev_t *TG[2] = {&TIMERG0, &TIMERG1};
|
||||
static portMUX_TYPE timer_spinlock[TIMER_GROUP_MAX] = {portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED};
|
||||
|
||||
#define TIMER_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux);
|
||||
#define TIMER_EXIT_CRITICAL(mux) portEXIT_CRITICAL(mux);
|
||||
|
||||
esp_err_t timer_get_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t* timer_val)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_val != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG);
|
||||
portENTER_CRITICAL(&timer_spinlock[group_num]);
|
||||
TG[group_num]->hw_timer[timer_num].update = 1;
|
||||
*timer_val = ((uint64_t) TG[group_num]->hw_timer[timer_num].cnt_high << 32)
|
||||
| (TG[group_num]->hw_timer[timer_num].cnt_low);
|
||||
portEXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t timer_get_counter_time_sec(timer_group_t group_num, timer_idx_t timer_num, double* time)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(time != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG);
|
||||
|
||||
uint64_t timer_val;
|
||||
esp_err_t err = timer_get_counter_value(group_num, timer_num, &timer_val);
|
||||
if (err == ESP_OK) {
|
||||
uint16_t div = TG[group_num]->hw_timer[timer_num].config.divider;
|
||||
*time = (double)timer_val * div / TIMER_BASE_CLK;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t timer_set_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t load_val)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
|
||||
TG[group_num]->hw_timer[timer_num].load_high = (uint32_t) (load_val >> 32);
|
||||
TG[group_num]->hw_timer[timer_num].load_low = (uint32_t) load_val;
|
||||
TG[group_num]->hw_timer[timer_num].reload = 1;
|
||||
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t timer_start(timer_group_t group_num, timer_idx_t timer_num)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
|
||||
TG[group_num]->hw_timer[timer_num].config.enable = 1;
|
||||
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t timer_pause(timer_group_t group_num, timer_idx_t timer_num)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
|
||||
TG[group_num]->hw_timer[timer_num].config.enable = 0;
|
||||
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t timer_set_counter_mode(timer_group_t group_num, timer_idx_t timer_num, timer_count_dir_t counter_dir)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(counter_dir < TIMER_COUNT_MAX, TIMER_COUNT_DIR_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
|
||||
TG[group_num]->hw_timer[timer_num].config.increase = counter_dir;
|
||||
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t timer_set_auto_reload(timer_group_t group_num, timer_idx_t timer_num, timer_autoreload_t reload)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(reload < TIMER_AUTORELOAD_MAX, TIMER_AUTORELOAD_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
|
||||
TG[group_num]->hw_timer[timer_num].config.autoreload = reload;
|
||||
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t timer_set_divider(timer_group_t group_num, timer_idx_t timer_num, uint16_t divider)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
|
||||
int timer_en = TG[group_num]->hw_timer[timer_num].config.enable;
|
||||
TG[group_num]->hw_timer[timer_num].config.enable = 0;
|
||||
TG[group_num]->hw_timer[timer_num].config.divider = divider;
|
||||
TG[group_num]->hw_timer[timer_num].config.enable = timer_en;
|
||||
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t timer_set_alarm_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_value)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
|
||||
TG[group_num]->hw_timer[timer_num].alarm_high = (uint32_t) (alarm_value >> 32);
|
||||
TG[group_num]->hw_timer[timer_num].alarm_low = (uint32_t) alarm_value;
|
||||
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t timer_get_alarm_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t* alarm_value)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(alarm_value != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG);
|
||||
portENTER_CRITICAL(&timer_spinlock[group_num]);
|
||||
*alarm_value = ((uint64_t) TG[group_num]->hw_timer[timer_num].alarm_high << 32)
|
||||
| (TG[group_num]->hw_timer[timer_num].alarm_low);
|
||||
portEXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_alarm_t alarm_en)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(alarm_en < TIMER_ALARM_MAX, TIMER_ALARM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
|
||||
TG[group_num]->hw_timer[timer_num].config.alarm_en = alarm_en;
|
||||
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num, int timer_intr_num,
|
||||
timer_intr_mode_t intr_type, void (*fn)(void*), void * arg)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(fn != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG);
|
||||
|
||||
ESP_INTR_DISABLE(timer_intr_num);
|
||||
int intr_source = 0;
|
||||
switch(group_num) {
|
||||
case TIMER_GROUP_0:
|
||||
default:
|
||||
if(intr_type == TIMER_INTR_LEVEL) {
|
||||
intr_source = ETS_TG0_T0_LEVEL_INTR_SOURCE + timer_num;
|
||||
} else {
|
||||
intr_source = ETS_TG0_T0_EDGE_INTR_SOURCE + timer_num;
|
||||
}
|
||||
break;
|
||||
case TIMER_GROUP_1:
|
||||
if(intr_type == TIMER_INTR_LEVEL) {
|
||||
intr_source = ETS_TG1_T0_LEVEL_INTR_SOURCE + timer_num;
|
||||
} else {
|
||||
intr_source = ETS_TG1_T0_EDGE_INTR_SOURCE + timer_num;
|
||||
}
|
||||
break;
|
||||
}
|
||||
intr_matrix_set(xPortGetCoreID(), intr_source, timer_intr_num);
|
||||
xt_set_interrupt_handler(timer_intr_num, fn, arg);
|
||||
ESP_INTR_ENABLE(timer_intr_num);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, timer_config_t *config)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(config != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG);
|
||||
|
||||
if(group_num == 0) {
|
||||
periph_module_enable(PERIPH_TIMG0_MODULE);
|
||||
} else if(group_num == 1) {
|
||||
periph_module_enable(PERIPH_TIMG1_MODULE);
|
||||
}
|
||||
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
|
||||
TG[group_num]->hw_timer[timer_num].config.autoreload = config->auto_reload;
|
||||
TG[group_num]->hw_timer[timer_num].config.divider = config->divider;
|
||||
TG[group_num]->hw_timer[timer_num].config.enable = config->counter_en;
|
||||
TG[group_num]->hw_timer[timer_num].config.increase = config->counter_dir;
|
||||
TG[group_num]->hw_timer[timer_num].config.alarm_en = config->alarm_en;
|
||||
TG[group_num]->hw_timer[timer_num].config.level_int_en = (config->intr_type == TIMER_INTR_LEVEL ? 1 : 0);
|
||||
TG[group_num]->hw_timer[timer_num].config.edge_int_en = (config->intr_type == TIMER_INTR_LEVEL ? 0 : 1);
|
||||
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t timer_get_config(timer_group_t group_num, timer_idx_t timer_num, timer_config_t *config)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(config != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
|
||||
config->alarm_en = TG[group_num]->hw_timer[timer_num].config.alarm_en;
|
||||
config->auto_reload = TG[group_num]->hw_timer[timer_num].config.autoreload;
|
||||
config->counter_dir = TG[group_num]->hw_timer[timer_num].config.increase;
|
||||
config->counter_dir = TG[group_num]->hw_timer[timer_num].config.divider;
|
||||
config->counter_en = TG[group_num]->hw_timer[timer_num].config.enable;
|
||||
if(TG[group_num]->hw_timer[timer_num].config.level_int_en) {
|
||||
config->intr_type =TIMER_INTR_LEVEL;
|
||||
}
|
||||
TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t timer_group_intr_enable(timer_group_t group_num, uint32_t en_mask)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
portENTER_CRITICAL(&timer_spinlock[group_num]);
|
||||
TG[group_num]->int_ena.val |= en_mask;
|
||||
portEXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t timer_group_intr_disable(timer_group_t group_num, uint32_t disable_mask)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
portENTER_CRITICAL(&timer_spinlock[group_num]);
|
||||
TG[group_num]->int_ena.val &= (~disable_mask);
|
||||
portEXIT_CRITICAL(&timer_spinlock[group_num]);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t timer_enable_intr(timer_group_t group_num, timer_idx_t timer_num)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
return timer_group_intr_enable(group_num, BIT(timer_num));
|
||||
}
|
||||
|
||||
esp_err_t timer_disable_intr(timer_group_t group_num, timer_idx_t timer_num)
|
||||
{
|
||||
TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG);
|
||||
return timer_group_intr_disable(group_num, BIT(timer_num));
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
COMPONENT_SRCDIRS := . hwcrypto
|
||||
|
||||
LIBS := core net80211 phy rtc pp wpa smartconfig coexist wps
|
||||
LIBS := core net80211 phy rtc pp wpa smartconfig coexist wps wpa2
|
||||
|
||||
LINKER_SCRIPTS += -T esp32_out.ld -T esp32.common.ld -T esp32.rom.ld -T esp32.peripherals.ld
|
||||
|
||||
|
@ -16,25 +16,8 @@
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/uart.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
typedef enum{
|
||||
XTAL_40M = 40,
|
||||
XTAL_26M = 26,
|
||||
XTAL_24M = 24,
|
||||
XTAL_AUTO = 0
|
||||
} xtal_freq_t;
|
||||
|
||||
typedef enum{
|
||||
CPU_80M = 1,
|
||||
CPU_160M = 2,
|
||||
CPU_240M = 3,
|
||||
} cpu_freq_t;
|
||||
|
||||
extern void phy_get_romfunc_addr();
|
||||
|
||||
// TODO: these functions need to be moved from librtc to ESP-IDF
|
||||
extern void rtc_init_lite(xtal_freq_t xtal_freq);
|
||||
extern void rtc_set_cpu_freq(cpu_freq_t cpu_freq);
|
||||
#include "phy.h"
|
||||
#include "rtc.h"
|
||||
|
||||
/*
|
||||
* This function is not exposed as an API at this point,
|
||||
|
@ -117,9 +117,7 @@ void IRAM_ATTR call_start_cpu0()
|
||||
//Flush and enable icache for APP CPU
|
||||
Cache_Flush(1);
|
||||
Cache_Read_Enable(1);
|
||||
//Un-stall the app cpu; the panic handler may have stalled it.
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_APPCPU_C1_M);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_APPCPU_C0_M);
|
||||
esp_cpu_unstall(1);
|
||||
//Enable clock gating and reset the app cpu.
|
||||
SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_C_REG, DPORT_APPCPU_RUNSTALL);
|
||||
@ -155,6 +153,7 @@ void IRAM_ATTR call_start_cpu1()
|
||||
|
||||
void start_cpu0_default(void)
|
||||
{
|
||||
esp_setup_syscall_table();
|
||||
//Enable trace memory and immediately start trace.
|
||||
#if CONFIG_MEMMAP_TRACEMEM
|
||||
#if CONFIG_MEMMAP_TRACEMEM_TWOBANKS
|
||||
@ -175,7 +174,6 @@ void start_cpu0_default(void)
|
||||
#if CONFIG_TASK_WDT
|
||||
esp_task_wdt_init();
|
||||
#endif
|
||||
esp_setup_syscall_table();
|
||||
esp_setup_time_syscalls();
|
||||
esp_vfs_dev_uart_register();
|
||||
esp_reent_init(_GLOBAL_REENT);
|
||||
|
44
components/esp32/cpu_util.c
Normal file
44
components/esp32/cpu_util.c
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2013-2016 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 "esp_attr.h"
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
void IRAM_ATTR esp_cpu_stall(int cpu_id)
|
||||
{
|
||||
if (cpu_id == 1) {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_APPCPU_C1_M);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21<<RTC_CNTL_SW_STALL_APPCPU_C1_S);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_APPCPU_C0_M);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, 2<<RTC_CNTL_SW_STALL_APPCPU_C0_S);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_PROCPU_C1_M);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21<<RTC_CNTL_SW_STALL_PROCPU_C1_S);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_PROCPU_C0_M);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, 2<<RTC_CNTL_SW_STALL_PROCPU_C0_S);
|
||||
}
|
||||
}
|
||||
|
||||
void IRAM_ATTR esp_cpu_unstall(int cpu_id)
|
||||
{
|
||||
if (cpu_id == 1) {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_APPCPU_C1_M);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_APPCPU_C0_M);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_PROCPU_C1_M);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_PROCPU_C0_M);
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@
|
||||
#include "soc/dport_reg.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_deepsleep.h"
|
||||
#include "rtc.h"
|
||||
|
||||
/* Updating RTC_MEMORY_CRC_REG register via set_rtc_memory_crc()
|
||||
is not thread-safe. */
|
||||
@ -46,3 +47,21 @@ void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void) {
|
||||
}
|
||||
|
||||
void __attribute__((weak, alias("esp_default_wake_deep_sleep"))) esp_wake_deep_sleep(void);
|
||||
|
||||
void esp_deep_sleep(uint64_t time_in_us)
|
||||
{
|
||||
rtc_set_cpu_freq(CPU_XTAL);
|
||||
if (esp_get_deep_sleep_wake_stub() == NULL) {
|
||||
esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep);
|
||||
}
|
||||
uint32_t period = rtc_slowck_cali(CALI_RTC_MUX, 128);
|
||||
uint32_t cycle_l, cycle_h;
|
||||
rtc_usec2rtc(time_in_us >> 32, time_in_us, period, &cycle_h, &cycle_l);
|
||||
rtc_slp_prep_lite(1, 0);
|
||||
rtc_sleep(cycle_h, cycle_l, TIMER_EXPIRE_EN, 0);
|
||||
while (1) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void system_deep_sleep(uint64_t) __attribute__((alias("esp_deep_sleep")));
|
||||
|
41
components/esp32/hw_random.c
Normal file
41
components/esp32/hw_random.c
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2016 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 <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "esp_attr.h"
|
||||
#include "soc/wdev_reg.h"
|
||||
#include "freertos/FreeRTOSConfig.h"
|
||||
#include "xtensa/core-macros.h"
|
||||
|
||||
uint32_t IRAM_ATTR esp_random(void)
|
||||
{
|
||||
/* The PRNG which implements WDEV_RANDOM register gets 2 bits
|
||||
* of extra entropy from a hardware randomness source every APB clock cycle.
|
||||
* To make sure entropy is not drained faster than it is added,
|
||||
* this function needs to wait for at least 16 APB clock cycles after reading
|
||||
* previous word. This implementation may actually wait a bit longer
|
||||
* due to extra time spent in arithmetic and branch statements.
|
||||
*/
|
||||
|
||||
static uint32_t last_ccount = 0;
|
||||
uint32_t ccount;
|
||||
do {
|
||||
ccount = XTHAL_GET_CCOUNT();
|
||||
} while (ccount - last_ccount < XT_CLOCK_FREQ / APB_CLK_FREQ * 16);
|
||||
last_ccount = ccount;
|
||||
return REG_READ(WDEV_RND_REG);
|
||||
}
|
@ -28,6 +28,7 @@
|
||||
#include <string.h>
|
||||
#include "hwcrypto/aes.h"
|
||||
#include "rom/aes.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include <sys/lock.h>
|
||||
|
||||
static _lock_t aes_lock;
|
||||
@ -36,14 +37,23 @@ void esp_aes_acquire_hardware( void )
|
||||
{
|
||||
/* newlib locks lazy initialize on ESP-IDF */
|
||||
_lock_acquire(&aes_lock);
|
||||
ets_aes_enable();
|
||||
/* Enable AES hardware */
|
||||
REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_AES);
|
||||
/* Clear reset on digital signature & secure boot units,
|
||||
otherwise AES unit is held in reset also. */
|
||||
REG_CLR_BIT(DPORT_PERI_RST_EN_REG,
|
||||
DPORT_PERI_EN_AES
|
||||
| DPORT_PERI_EN_DIGITAL_SIGNATURE
|
||||
| DPORT_PERI_EN_SECUREBOOT);
|
||||
}
|
||||
|
||||
void esp_aes_release_hardware( void )
|
||||
{
|
||||
uint8_t zero[256/8] = { 0 };
|
||||
ets_aes_setkey_enc(zero, AES256);
|
||||
ets_aes_disable();
|
||||
/* Disable AES hardware */
|
||||
REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_AES);
|
||||
/* Don't return other units to reset, as this pulls
|
||||
reset on RSA & SHA units, respectively. */
|
||||
REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_AES);
|
||||
_lock_release(&aes_lock);
|
||||
}
|
||||
|
||||
|
@ -26,242 +26,264 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/lock.h>
|
||||
#include <byteswap.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "hwcrypto/sha.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
|
||||
|
||||
static _lock_t sha_lock;
|
||||
|
||||
void esp_sha_acquire_hardware( void )
|
||||
{
|
||||
/* newlib locks lazy initialize on ESP-IDF */
|
||||
_lock_acquire(&sha_lock);
|
||||
ets_sha_enable();
|
||||
inline static uint32_t SHA_LOAD_REG(esp_sha_type sha_type) {
|
||||
return SHA_1_LOAD_REG + sha_type * 0x10;
|
||||
}
|
||||
|
||||
void esp_sha_release_hardware( void )
|
||||
{
|
||||
/* Want to empty internal SHA buffers where possible,
|
||||
need to check if this is sufficient for this. */
|
||||
SHA_CTX zero = { 0 };
|
||||
ets_sha_init(&zero);
|
||||
ets_sha_disable();
|
||||
_lock_release(&sha_lock);
|
||||
inline static uint32_t SHA_BUSY_REG(esp_sha_type sha_type) {
|
||||
return SHA_1_BUSY_REG + sha_type * 0x10;
|
||||
}
|
||||
|
||||
/* Generic esp_shaX_update implementation */
|
||||
static void esp_sha_update( esp_sha_context *ctx, const unsigned char *input, size_t ilen, size_t block_size)
|
||||
inline static uint32_t SHA_START_REG(esp_sha_type sha_type) {
|
||||
return SHA_1_START_REG + sha_type * 0x10;
|
||||
}
|
||||
|
||||
inline static uint32_t SHA_CONTINUE_REG(esp_sha_type sha_type) {
|
||||
return SHA_1_CONTINUE_REG + sha_type * 0x10;
|
||||
}
|
||||
|
||||
/* Single lock for SHA engine memory block
|
||||
*/
|
||||
static _lock_t memory_block_lock;
|
||||
|
||||
typedef struct {
|
||||
_lock_t lock;
|
||||
bool in_use;
|
||||
} sha_engine_state;
|
||||
|
||||
/* Pointer to state of each concurrent SHA engine.
|
||||
|
||||
Indexes:
|
||||
0 = SHA1
|
||||
1 = SHA2_256
|
||||
2 = SHA2_384 or SHA2_512
|
||||
*/
|
||||
static sha_engine_state engine_states[3];
|
||||
|
||||
/* Index into the sha_engine_state array */
|
||||
inline static size_t sha_engine_index(esp_sha_type type) {
|
||||
switch(type) {
|
||||
case SHA1:
|
||||
return 0;
|
||||
case SHA2_256:
|
||||
return 1;
|
||||
default:
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return digest length (in bytes) for a given SHA type */
|
||||
inline static size_t sha_length(esp_sha_type type) {
|
||||
switch(type) {
|
||||
case SHA1:
|
||||
return 20;
|
||||
case SHA2_256:
|
||||
return 32;
|
||||
case SHA2_384:
|
||||
return 48;
|
||||
case SHA2_512:
|
||||
return 64;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return block size (in bytes) for a given SHA type */
|
||||
inline static size_t block_length(esp_sha_type type) {
|
||||
switch(type) {
|
||||
case SHA1:
|
||||
case SHA2_256:
|
||||
return 64;
|
||||
case SHA2_384:
|
||||
case SHA2_512:
|
||||
return 128;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void esp_sha_lock_memory_block(void)
|
||||
{
|
||||
/* Feed the SHA engine one block at a time */
|
||||
_lock_acquire(&memory_block_lock);
|
||||
}
|
||||
|
||||
void esp_sha_unlock_memory_block(void)
|
||||
{
|
||||
_lock_release(&memory_block_lock);
|
||||
}
|
||||
|
||||
/* Lock to hold when changing SHA engine state,
|
||||
allows checking of sha_engines_all_idle()
|
||||
*/
|
||||
static _lock_t state_change_lock;
|
||||
|
||||
inline static bool sha_engines_all_idle() {
|
||||
return !engine_states[0].in_use
|
||||
&& !engine_states[1].in_use
|
||||
&& !engine_states[2].in_use;
|
||||
}
|
||||
|
||||
static void esp_sha_lock_engine_inner(sha_engine_state *engine);
|
||||
|
||||
bool esp_sha_try_lock_engine(esp_sha_type sha_type)
|
||||
{
|
||||
sha_engine_state *engine = &engine_states[sha_engine_index(sha_type)];
|
||||
if(_lock_try_acquire(&engine->lock) != 0) {
|
||||
/* This SHA engine is already in use */
|
||||
return false;
|
||||
} else {
|
||||
esp_sha_lock_engine_inner(engine);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void esp_sha_lock_engine(esp_sha_type sha_type)
|
||||
{
|
||||
sha_engine_state *engine = &engine_states[sha_engine_index(sha_type)];
|
||||
_lock_acquire(&engine->lock);
|
||||
esp_sha_lock_engine_inner(engine);
|
||||
}
|
||||
|
||||
static void esp_sha_lock_engine_inner(sha_engine_state *engine)
|
||||
{
|
||||
_lock_acquire(&state_change_lock);
|
||||
|
||||
if (sha_engines_all_idle()) {
|
||||
/* Enable SHA hardware */
|
||||
REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA);
|
||||
/* also clear reset on secure boot, otherwise SHA is held in reset */
|
||||
REG_CLR_BIT(DPORT_PERI_RST_EN_REG,
|
||||
DPORT_PERI_EN_SHA
|
||||
| DPORT_PERI_EN_SECUREBOOT);
|
||||
ets_sha_enable();
|
||||
}
|
||||
|
||||
_lock_release(&state_change_lock);
|
||||
|
||||
assert( !engine->in_use && "in_use flag should be cleared" );
|
||||
engine->in_use = true;
|
||||
}
|
||||
|
||||
|
||||
void esp_sha_unlock_engine(esp_sha_type sha_type)
|
||||
{
|
||||
sha_engine_state *engine = &engine_states[sha_engine_index(sha_type)];
|
||||
|
||||
_lock_acquire(&state_change_lock);
|
||||
|
||||
assert( engine->in_use && "in_use flag should be set" );
|
||||
engine->in_use = false;
|
||||
|
||||
if (sha_engines_all_idle()) {
|
||||
/* Disable SHA hardware */
|
||||
/* Don't assert reset on secure boot, otherwise AES is held in reset */
|
||||
REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_SHA);
|
||||
REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA);
|
||||
}
|
||||
|
||||
_lock_release(&state_change_lock);
|
||||
|
||||
_lock_release(&engine->lock);
|
||||
}
|
||||
|
||||
void esp_sha_wait_idle(void)
|
||||
{
|
||||
while(REG_READ(SHA_1_BUSY_REG) == 1) {}
|
||||
while(REG_READ(SHA_256_BUSY_REG) == 1) {}
|
||||
while(REG_READ(SHA_384_BUSY_REG) == 1) {}
|
||||
while(REG_READ(SHA_512_BUSY_REG) == 1) {}
|
||||
}
|
||||
|
||||
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
|
||||
{
|
||||
sha_engine_state *engine = &engine_states[sha_engine_index(sha_type)];
|
||||
assert(engine->in_use && "SHA engine should be locked" );
|
||||
|
||||
esp_sha_lock_memory_block();
|
||||
|
||||
esp_sha_wait_idle();
|
||||
|
||||
REG_WRITE(SHA_LOAD_REG(sha_type), 1);
|
||||
while(REG_READ(SHA_BUSY_REG(sha_type)) == 1) { }
|
||||
|
||||
uint32_t *digest_state_words = (uint32_t *)digest_state;
|
||||
uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
|
||||
if(sha_type == SHA2_384 || sha_type == SHA2_512) {
|
||||
/* for these ciphers using 64-bit states, swap each pair of words */
|
||||
for(int i = 0; i < sha_length(sha_type)/4; i += 2) {
|
||||
digest_state_words[i+1] = reg_addr_buf[i];
|
||||
digest_state_words[i]= reg_addr_buf[i+1];
|
||||
}
|
||||
} else {
|
||||
memcpy(digest_state_words, reg_addr_buf, sha_length(sha_type));
|
||||
}
|
||||
asm volatile ("memw");
|
||||
|
||||
esp_sha_unlock_memory_block();
|
||||
}
|
||||
|
||||
void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block)
|
||||
{
|
||||
sha_engine_state *engine = &engine_states[sha_engine_index(sha_type)];
|
||||
assert(engine->in_use && "SHA engine should be locked" );
|
||||
|
||||
esp_sha_lock_memory_block();
|
||||
|
||||
esp_sha_wait_idle();
|
||||
|
||||
/* Fill the data block */
|
||||
uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
|
||||
uint32_t *data_words = (uint32_t *)data_block;
|
||||
for (int i = 0; i < block_length(sha_type) / 4; i++) {
|
||||
reg_addr_buf[i] = __bswap_32(data_words[i]);
|
||||
}
|
||||
asm volatile ("memw");
|
||||
|
||||
if(is_first_block) {
|
||||
REG_WRITE(SHA_START_REG(sha_type), 1);
|
||||
} else {
|
||||
REG_WRITE(SHA_CONTINUE_REG(sha_type), 1);
|
||||
}
|
||||
|
||||
esp_sha_unlock_memory_block();
|
||||
|
||||
/* Note: deliberately not waiting for this operation to complete,
|
||||
as a performance tweak - delay waiting until the next time we need the SHA
|
||||
unit, instead.
|
||||
*/
|
||||
}
|
||||
|
||||
void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output)
|
||||
{
|
||||
size_t block_len = block_length(sha_type);
|
||||
|
||||
esp_sha_lock_engine(sha_type);
|
||||
|
||||
SHA_CTX ctx;
|
||||
ets_sha_init(&ctx);
|
||||
while(ilen > 0) {
|
||||
size_t chunk_len = (ilen > block_size) ? block_size : ilen;
|
||||
ets_sha_update(&ctx->context, ctx->context_type, input, chunk_len * 8);
|
||||
size_t chunk_len = (ilen > block_len) ? block_len : ilen;
|
||||
esp_sha_lock_memory_block();
|
||||
esp_sha_wait_idle();
|
||||
ets_sha_update(&ctx, sha_type, input, chunk_len * 8);
|
||||
esp_sha_unlock_memory_block();
|
||||
input += chunk_len;
|
||||
ilen -= chunk_len;
|
||||
}
|
||||
esp_sha_lock_memory_block();
|
||||
esp_sha_wait_idle();
|
||||
ets_sha_finish(&ctx, sha_type, output);
|
||||
esp_sha_unlock_memory_block();
|
||||
|
||||
esp_sha_unlock_engine(sha_type);
|
||||
}
|
||||
|
||||
void esp_sha1_init( esp_sha_context *ctx )
|
||||
{
|
||||
bzero( ctx, sizeof( esp_sha_context ) );
|
||||
}
|
||||
|
||||
void esp_sha1_free( esp_sha_context *ctx )
|
||||
{
|
||||
if ( ctx == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
bzero( ctx, sizeof( esp_sha_context ) );
|
||||
}
|
||||
|
||||
void esp_sha1_clone( esp_sha_context *dst, const esp_sha_context *src )
|
||||
{
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 context setup
|
||||
*/
|
||||
void esp_sha1_start( esp_sha_context *ctx )
|
||||
{
|
||||
ctx->context_type = SHA1;
|
||||
esp_sha_acquire_hardware();
|
||||
ets_sha_init(&ctx->context);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 process buffer
|
||||
*/
|
||||
void esp_sha1_update( esp_sha_context *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
esp_sha_update(ctx, input, ilen, 64);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 final digest
|
||||
*/
|
||||
void esp_sha1_finish( esp_sha_context *ctx, unsigned char output[20] )
|
||||
{
|
||||
ets_sha_finish(&ctx->context, ctx->context_type, output);
|
||||
esp_sha_release_hardware();
|
||||
}
|
||||
|
||||
/* Full SHA-1 calculation */
|
||||
void esp_sha1( const unsigned char *input, size_t ilen, unsigned char output[20] )
|
||||
{
|
||||
esp_sha_context ctx;
|
||||
|
||||
esp_sha1_init( &ctx );
|
||||
esp_sha1_start( &ctx );
|
||||
esp_sha1_update( &ctx, input, ilen );
|
||||
esp_sha1_finish( &ctx, output );
|
||||
esp_sha1_free( &ctx );
|
||||
}
|
||||
|
||||
void esp_sha256_init( esp_sha_context *ctx )
|
||||
{
|
||||
bzero( ctx, sizeof( esp_sha_context ) );
|
||||
}
|
||||
|
||||
void esp_sha256_free( esp_sha_context *ctx )
|
||||
{
|
||||
if ( ctx == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
bzero( ctx, sizeof( esp_sha_context ) );
|
||||
}
|
||||
|
||||
void esp_sha256_clone( esp_sha_context *dst, const esp_sha_context *src )
|
||||
{
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-256 context setup
|
||||
*/
|
||||
void esp_sha256_start( esp_sha_context *ctx, int is224 )
|
||||
{
|
||||
if ( is224 == 0 ) {
|
||||
/* SHA-256 */
|
||||
ctx->context_type = SHA2_256;
|
||||
esp_sha_acquire_hardware();
|
||||
ets_sha_init(&ctx->context);
|
||||
} else {
|
||||
/* SHA-224 is not supported! */
|
||||
ctx->context_type = SHA_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-256 process buffer
|
||||
*/
|
||||
void esp_sha256_update( esp_sha_context *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
if( ctx->context_type == SHA2_256 ) {
|
||||
esp_sha_update(ctx, input, ilen, 64);
|
||||
}
|
||||
/* SHA-224 is a no-op */
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-256 final digest
|
||||
*/
|
||||
void esp_sha256_finish( esp_sha_context *ctx, unsigned char output[32] )
|
||||
{
|
||||
if ( ctx->context_type == SHA2_256 ) {
|
||||
ets_sha_finish(&ctx->context, ctx->context_type, output);
|
||||
esp_sha_release_hardware();
|
||||
} else {
|
||||
/* No hardware SHA-224 support, but mbedTLS API doesn't allow failure.
|
||||
For now, zero the output to make it clear it's not valid. */
|
||||
bzero( output, 28 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Full SHA-256 calculation
|
||||
*/
|
||||
void esp_sha256( const unsigned char *input, size_t ilen, unsigned char output[32], int is224 )
|
||||
{
|
||||
esp_sha_context ctx;
|
||||
|
||||
esp_sha256_init( &ctx );
|
||||
esp_sha256_start( &ctx, is224 );
|
||||
esp_sha256_update( &ctx, input, ilen );
|
||||
esp_sha256_finish( &ctx, output );
|
||||
esp_sha256_free( &ctx );
|
||||
}
|
||||
|
||||
|
||||
/////
|
||||
void esp_sha512_init( esp_sha_context *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( esp_sha_context ) );
|
||||
}
|
||||
|
||||
void esp_sha512_free( esp_sha_context *ctx )
|
||||
{
|
||||
if ( ctx == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
bzero( ctx, sizeof( esp_sha_context ) );
|
||||
}
|
||||
|
||||
void esp_sha512_clone( esp_sha_context *dst, const esp_sha_context *src )
|
||||
{
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-512 context setup
|
||||
*/
|
||||
void esp_sha512_start( esp_sha_context *ctx, int is384 )
|
||||
{
|
||||
if ( is384 == 0 ) {
|
||||
/* SHA-512 */
|
||||
ctx->context_type = SHA2_512;
|
||||
} else {
|
||||
/* SHA-384 */
|
||||
ctx->context_type = SHA2_384;
|
||||
}
|
||||
esp_sha_acquire_hardware();
|
||||
ets_sha_init(&ctx->context);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-512 process buffer
|
||||
*/
|
||||
void esp_sha512_update( esp_sha_context *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
esp_sha_update(ctx, input, ilen, 128);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-512 final digest
|
||||
*/
|
||||
void esp_sha512_finish( esp_sha_context *ctx, unsigned char output[64] )
|
||||
{
|
||||
ets_sha_finish(&ctx->context, ctx->context_type, output);
|
||||
esp_sha_release_hardware();
|
||||
}
|
||||
|
||||
/*
|
||||
* Full SHA-512 calculation
|
||||
*/
|
||||
void esp_sha512( const unsigned char *input, size_t ilen, unsigned char output[64], int is384 )
|
||||
{
|
||||
esp_sha_context ctx;
|
||||
|
||||
esp_sha512_init( &ctx );
|
||||
esp_sha512_start( &ctx, is384 );
|
||||
esp_sha512_update( &ctx, input, ilen );
|
||||
esp_sha512_finish( &ctx, output );
|
||||
esp_sha512_free( &ctx );
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
|
@ -30,25 +30,34 @@ extern "C" {
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set the chip to deep-sleep mode.
|
||||
*
|
||||
* The device will automatically wake up after the deep-sleep time set
|
||||
* by the users. Upon waking up, the device boots up from user_init.
|
||||
*
|
||||
* @attention The parameter time_in_us to be "uint64" is for further development.
|
||||
* Only the low 32 bits of parameter time_in_us are avalable now.
|
||||
*
|
||||
* @param uint64 time_in_us : deep-sleep time, only the low 32bits are avalable now. unit: microsecond
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
void system_deep_sleep(uint64_t time_in_us);
|
||||
* @brief Enter deep-sleep mode
|
||||
*
|
||||
* The device will automatically wake up after the deep-sleep time
|
||||
* Upon waking up, the device calls deep sleep wake stub, and then proceeds
|
||||
* to load application.
|
||||
*
|
||||
* This function does not return.
|
||||
*
|
||||
* @param time_in_us deep-sleep time, unit: microsecond
|
||||
*/
|
||||
void esp_deep_sleep(uint64_t time_in_us) __attribute__((noreturn));
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enter deep-sleep mode
|
||||
*
|
||||
* Function has been renamed to esp_deep_sleep.
|
||||
* This name is deprecated and will be removed in a future version.
|
||||
*
|
||||
* @param time_in_us deep-sleep time, unit: microsecond
|
||||
*/
|
||||
void system_deep_sleep(uint64_t time_in_us) __attribute__((noreturn, deprecated));
|
||||
|
||||
/**
|
||||
* @brief Default stub to run on wake from deep sleep.
|
||||
*
|
||||
* Allows for executing code immediately on wake from sleep, before
|
||||
* the software bootloader or esp-idf app has started up.
|
||||
* the software bootloader or ESP-IDF app has started up.
|
||||
*
|
||||
* This function is weak-linked, so you can implement your own version
|
||||
* to run code immediately when the chip wakes from
|
||||
|
@ -16,7 +16,7 @@
|
||||
#define __ESP_SYSTEM_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_deepsleep.h"
|
||||
|
||||
@ -24,166 +24,107 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup System_APIs System APIs
|
||||
* @brief System APIs
|
||||
*/
|
||||
|
||||
/** @addtogroup System_APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @attention application don't need to call this function anymore. It do nothing and will
|
||||
* be removed in future version.
|
||||
*/
|
||||
void system_init(void) __attribute__ ((deprecated));
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get information of the SDK version.
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return Information of the SDK version.
|
||||
*/
|
||||
const char *system_get_sdk_version(void);
|
||||
|
||||
/**
|
||||
* @brief Reset to default settings.
|
||||
*
|
||||
* Reset to default settings of the following APIs : wifi_station_set_auto_connect,
|
||||
* wifi_set_phy_mode, wifi_softap_set_config related, wifi_station_set_config
|
||||
* related, and wifi_set_opmode.
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return null
|
||||
* Function has been deprecated, please use esp_wifi_restore instead.
|
||||
* This name will be removed in a future release.
|
||||
*/
|
||||
void system_restore(void);
|
||||
void system_restore(void) __attribute__ ((deprecated));
|
||||
|
||||
/**
|
||||
* @brief Restart PRO and APP CPUs.
|
||||
*
|
||||
* This function can be called both from PRO and APP CPUs.
|
||||
* After successful restart, CPU reset reason will be SW_CPU_RESET.
|
||||
* Peripherals (except for WiFi, BT, UART0, SPI1, and legacy timers) are not reset.
|
||||
* This function does not return.
|
||||
*/
|
||||
void esp_restart(void) __attribute__ ((noreturn));
|
||||
|
||||
/**
|
||||
* @brief Restart system.
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return null
|
||||
* Function has been renamed to esp_restart.
|
||||
* This name will be removed in a future release.
|
||||
*/
|
||||
void system_restart(void);
|
||||
void system_restart(void) __attribute__ ((deprecated, noreturn));
|
||||
|
||||
/**
|
||||
* @brief Get system time, unit: microsecond.
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return System time, unit: microsecond.
|
||||
* This function is deprecated. Use 'gettimeofday' function for 64-bit precision.
|
||||
* This definition will be removed in a future release.
|
||||
*/
|
||||
uint32_t system_get_time(void);
|
||||
uint32_t system_get_time(void) __attribute__ ((deprecated));
|
||||
|
||||
/**
|
||||
* @brief Get the size of available heap.
|
||||
*
|
||||
* @param null
|
||||
* Note that the returned value may be larger than the maximum contiguous block
|
||||
* which can be allocated.
|
||||
*
|
||||
* @return Available heap size.
|
||||
* @return Available heap size, in bytes.
|
||||
*/
|
||||
uint32_t system_get_free_heap_size(void);
|
||||
uint32_t esp_get_free_heap_size(void);
|
||||
|
||||
/**
|
||||
* @brief Get RTC time, unit: RTC clock cycle.
|
||||
* @brief Get the size of available heap.
|
||||
*
|
||||
* @param null
|
||||
* Function has been renamed to esp_get_free_heap_size.
|
||||
* This name will be removed in a future release.
|
||||
*
|
||||
* @return RTC time.
|
||||
* @return Available heap size, in bytes.
|
||||
*/
|
||||
uint64_t system_get_rtc_time(void);
|
||||
uint32_t system_get_free_heap_size(void) __attribute__ ((deprecated));
|
||||
|
||||
/**
|
||||
* @brief Read user data from the RTC memory.
|
||||
*
|
||||
* The user data segment (1024 bytes, as shown below) is used to store user data.
|
||||
*
|
||||
* |<---- system data(512 bytes) ---->|<----------- user data(1024 bytes) --------->|
|
||||
*
|
||||
* @attention Read and write unit for data stored in the RTC memory is 4 bytes.
|
||||
* @attention src_addr is the block number (4 bytes per block). So when reading data
|
||||
* at the beginning of the user data segment, src_addr will be 512/4 = 128,
|
||||
* n will be data length.
|
||||
*
|
||||
* @param uint16 src : source address of rtc memory, src_addr >= 128
|
||||
* @param void *dst : data pointer
|
||||
* @param uint16 n : data length, unit: byte
|
||||
*
|
||||
* @return true : succeed
|
||||
* @return false : fail
|
||||
*/
|
||||
bool system_rtc_mem_read(uint16_t src, void *dst, uint16_t n);
|
||||
|
||||
/**
|
||||
* @brief Write user data to the RTC memory.
|
||||
*
|
||||
* During deep-sleep, only RTC is working. So users can store their data
|
||||
* in RTC memory if it is needed. The user data segment below (1024 bytes)
|
||||
* is used to store the user data.
|
||||
*
|
||||
* |<---- system data(512 bytes) ---->|<----------- user data(1024 bytes) --------->|
|
||||
*
|
||||
* @attention Read and write unit for data stored in the RTC memory is 4 bytes.
|
||||
* @attention src_addr is the block number (4 bytes per block). So when storing data
|
||||
* at the beginning of the user data segment, src_addr will be 512/4 = 128,
|
||||
* n will be data length.
|
||||
*
|
||||
* @param uint16 src : source address of rtc memory, src_addr >= 128
|
||||
* @param void *dst : data pointer
|
||||
* @param uint16 n : data length, unit: byte
|
||||
*
|
||||
* @return true : succeed
|
||||
* @return false : fail
|
||||
*/
|
||||
bool system_rtc_mem_write(uint16_t dst, const void *src, uint16_t n);
|
||||
|
||||
/** \defgroup System_boot_APIs Boot APIs
|
||||
* @brief boot APIs
|
||||
*/
|
||||
|
||||
/** @addtogroup System_boot_APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** \defgroup Hardware_MAC_APIs Hardware MAC APIs
|
||||
* @brief Hardware MAC address APIs
|
||||
*
|
||||
* In WiFi MAC, only ESP32 station MAC is the hardware MAC, ESP32 softAP MAC is a software MAC
|
||||
* calculated from ESP32 station MAC.
|
||||
* So users need to call wifi_get_macaddr to query the ESP32 softAP MAC if ESP32 station MAC changed.
|
||||
*
|
||||
*/
|
||||
|
||||
/** @addtogroup Hardware_MAC_APIs
|
||||
* @{
|
||||
*/
|
||||
* @brief Get one random 32-bit word from hardware RNG
|
||||
*
|
||||
* @return random value between 0 and UINT32_MAX
|
||||
*/
|
||||
uint32_t esp_random(void);
|
||||
|
||||
/**
|
||||
* @brief Read hardware MAC address.
|
||||
*
|
||||
* @param uint8 mac[6] : the hardware MAC address, length: 6 bytes.
|
||||
* In WiFi MAC, only ESP32 station MAC is the hardware MAC, ESP32 softAP MAC is a software MAC
|
||||
* calculated from ESP32 station MAC.
|
||||
* So users need to call esp_wifi_get_macaddr to query the ESP32 softAP MAC if ESP32 station MAC changed.
|
||||
*
|
||||
* @return esp_err_t
|
||||
* @param mac hardware MAC address, length: 6 bytes.
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
esp_err_t system_efuse_read_mac(uint8_t mac[6]);
|
||||
|
||||
esp_err_t esp_efuse_read_mac(uint8_t* mac);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @brief Read hardware MAC address.
|
||||
*
|
||||
* Function has been renamed to esp_efuse_read_mac.
|
||||
* This name will be removed in a future release.
|
||||
*
|
||||
* @param mac hardware MAC address, length: 6 bytes.
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
|
||||
esp_err_t system_efuse_read_mac(uint8_t mac[6]) __attribute__ ((deprecated));
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
* Get SDK version
|
||||
*
|
||||
* This function is deprecated and will be removed in a future release.
|
||||
*
|
||||
* @return constant string "master"
|
||||
*/
|
||||
const char* system_get_sdk_version(void) __attribute__ ((deprecated));
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -22,52 +22,4 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define __ATTRIB_PACK __attribute__ ((packed))
|
||||
#define __ATTRIB_PRINTF __attribute__ ((format (printf, 1, 2)))
|
||||
#define __ATTRIB_NORETURN __attribute__ ((noreturn))
|
||||
#define __ATTRIB_ALIGN(x) __attribute__ ((aligned((x))))
|
||||
#define INLINE __inline__
|
||||
|
||||
#define LOCAL static
|
||||
|
||||
/* probably should not put STATUS here */
|
||||
typedef enum {
|
||||
OK = 0,
|
||||
FAIL,
|
||||
PENDING,
|
||||
BUSY,
|
||||
CANCEL,
|
||||
} STATUS;
|
||||
|
||||
//#define _LITTLE_ENDIAN 1234
|
||||
//#define _BYTE_ORDER == _LITTLE_ENDIAN
|
||||
|
||||
#define ASSERT( x ) do { \
|
||||
if (!(x)) { \
|
||||
printf("%s %u\n", __FILE__, __LINE__); \
|
||||
while (1) { \
|
||||
asm volatile("nop"); \
|
||||
}; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* #if __GNUC_PREREQ__(4, 1) */
|
||||
#ifndef __GNUC__
|
||||
#if 1
|
||||
#define __offsetof(type, field) __builtin_offsetof(type, field)
|
||||
#else
|
||||
#define __offsetof(type, field) ((size_t)(&((type *)0)->field))
|
||||
#endif
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
|
||||
/* Macros for counting and rounding. */
|
||||
#ifndef howmany
|
||||
#define howmany(x, y) (((x)+((y)-1))/(y))
|
||||
#endif
|
||||
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (char *)__mptr - __offsetof(type,member) );})
|
||||
|
||||
#endif /* __ESP_TYPES_H__ */
|
||||
|
@ -186,6 +186,21 @@ esp_err_t esp_wifi_start(void);
|
||||
*/
|
||||
esp_err_t esp_wifi_stop(void);
|
||||
|
||||
/**
|
||||
* @brief Restore WiFi stack persistent settings to default values
|
||||
*
|
||||
* This function will reset settings made using the following APIs:
|
||||
* - esp_wifi_get_auto_connect,
|
||||
* - esp_wifi_set_protocol,
|
||||
* - esp_wifi_set_config related
|
||||
* - esp_wifi_set_mode
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by eps_wifi_init
|
||||
*/
|
||||
esp_err_t esp_wifi_restore(void);
|
||||
|
||||
/**
|
||||
* @brief Connect the ESP32 WiFi station to the AP.
|
||||
*
|
||||
|
@ -43,10 +43,9 @@ extern "C" {
|
||||
/**
|
||||
* @brief get whether the wifi driver is allowed to transmit data or not
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return true : upper layer should stop to transmit data to wifi driver
|
||||
* @return false : upper layer can transmit data to wifi driver
|
||||
* @return
|
||||
* - true : upper layer should stop to transmit data to wifi driver
|
||||
* - false : upper layer can transmit data to wifi driver
|
||||
*/
|
||||
bool esp_wifi_internal_tx_is_stop(void);
|
||||
|
||||
@ -54,8 +53,6 @@ bool esp_wifi_internal_tx_is_stop(void);
|
||||
* @brief free the rx buffer which allocated by wifi driver
|
||||
*
|
||||
* @param void* buffer: rx buffer pointer
|
||||
*
|
||||
* @return nonoe
|
||||
*/
|
||||
void esp_wifi_internal_free_rx_buffer(void* buffer);
|
||||
|
||||
@ -78,7 +75,6 @@ int esp_wifi_internal_tx(wifi_interface_t wifi_if, void *buffer, u16_t len);
|
||||
* @brief The WiFi RX callback function
|
||||
*
|
||||
* Each time the WiFi need to forward the packets to high layer, the callback function will be called
|
||||
*
|
||||
*/
|
||||
typedef esp_err_t (*wifi_rxcb_t)(void *buffer, uint16_t len, void *eb);
|
||||
|
||||
@ -90,18 +86,18 @@ typedef esp_err_t (*wifi_rxcb_t)(void *buffer, uint16_t len, void *eb);
|
||||
* @param wifi_interface_t ifx : interface
|
||||
* @param wifi_rxcb_t fn : WiFi RX callback
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
* @return
|
||||
* - ESP_OK : succeed
|
||||
* - others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_internal_reg_rxcb(wifi_interface_t ifx, wifi_rxcb_t fn);
|
||||
|
||||
/**
|
||||
* @brief Notify WIFI driver that the station got ip successfully
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
* @return
|
||||
* - ESP_OK : succeed
|
||||
* - others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_internal_set_sta_ip(void);
|
||||
|
||||
|
@ -114,8 +114,6 @@ typedef struct {
|
||||
typedef enum {
|
||||
WIFI_PS_NONE, /**< No power save */
|
||||
WIFI_PS_MODEM, /**< Modem power save */
|
||||
WIFI_PS_LIGHT, /**< Light power save */
|
||||
WIFI_PS_MAC, /**< MAC power save */
|
||||
} wifi_ps_type_t;
|
||||
|
||||
#define WIFI_PROTOCOL_11B 1
|
||||
|
166
components/esp32/include/esp_wpa2.h
Normal file
166
components/esp32/include/esp_wpa2.h
Normal file
@ -0,0 +1,166 @@
|
||||
// Copyright 2015-2016 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.
|
||||
|
||||
#ifndef ESP_WPA2_H
|
||||
#define ESP_WPA2_H
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enable wpa2 enterprise authentication.
|
||||
*
|
||||
* @attention wpa2 enterprise authentication can only be used when ESP32 station is enabled.
|
||||
* wpa2 enterprise authentication can only support TLS, PEAP-MSCHAPv2 and TTLS-MSCHAPv2 method.
|
||||
*
|
||||
* @return ESP_ERR_WIFI_OK: succeed.
|
||||
* ESP_ERR_WIFI_NO_MEM: fail(internal memory malloc fail)
|
||||
*/
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_enable(void);
|
||||
|
||||
/**
|
||||
* @brief Disable wpa2 enterprise authentication.
|
||||
*
|
||||
* @attention wpa2 enterprise authentication can only be used when ESP32 station is enabled.
|
||||
* wpa2 enterprise authentication can only support TLS, PEAP-MSCHAPv2 and TTLS-MSCHAPv2 method.
|
||||
*
|
||||
* @return ESP_ERR_WIFI_OK: succeed.
|
||||
*/
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_disable(void);
|
||||
|
||||
/**
|
||||
* @brief Set username for PEAP/TTLS method.
|
||||
*
|
||||
* @attention The API only passes the parameter username to the global pointer variable in wpa2 enterprise module.
|
||||
*
|
||||
* @param username: point to address where stores the username;
|
||||
* len: length of username, limited to 1~127
|
||||
*
|
||||
* @return ESP_ERR_WIFI_OK: succeed
|
||||
* ESP_ERR_WIFI_ARG: fail(len <= 0 or len >= 128)
|
||||
* ESP_ERR_WIFI_NO_MEM: fail(internal memory malloc fail)
|
||||
*/
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_set_username(unsigned char *username, int len);
|
||||
|
||||
/**
|
||||
* @brief Clear username for PEAP/TTLS method.
|
||||
*/
|
||||
void esp_wifi_sta_wpa2_ent_clear_username(void);
|
||||
|
||||
/**
|
||||
* @brief Set password for PEAP/TTLS method..
|
||||
*
|
||||
* @attention The API only passes the parameter password to the global pointer variable in wpa2 enterprise module.
|
||||
*
|
||||
* @param password: point to address where stores the password;
|
||||
* len: length of password(len > 0)
|
||||
*
|
||||
* @return ESP_ERR_WIFI_OK: succeed
|
||||
* ESP_ERR_WIFI_ARG: fail(len <= 0)
|
||||
* ESP_ERR_WIFI_NO_MEM: fail(internal memory malloc fail)
|
||||
*/
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_set_password(unsigned char *password, int len);
|
||||
|
||||
/**
|
||||
* @brief Clear password for PEAP/TTLS method..
|
||||
*/
|
||||
void esp_wifi_sta_wpa2_ent_clear_password(void);
|
||||
|
||||
/**
|
||||
* @brief Set new password for MSCHAPv2 method..
|
||||
*
|
||||
* @attention The API only passes the parameter password to the global pointer variable in wpa2 enterprise module.
|
||||
* The new password is used to substitute the old password when eap-mschapv2 failure request message with error code ERROR_PASSWD_EXPIRED is received.
|
||||
*
|
||||
* @param password: point to address where stores the password;
|
||||
* len: length of password
|
||||
*
|
||||
* @return ESP_ERR_WIFI_OK: succeed
|
||||
* ESP_ERR_WIFI_ARG: fail(len <= 0)
|
||||
* ESP_ERR_WIFI_NO_MEM: fail(internal memory malloc fail)
|
||||
*/
|
||||
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_set_new_password(unsigned char *password, int len);
|
||||
|
||||
/**
|
||||
* @brief Clear new password for MSCHAPv2 method..
|
||||
*/
|
||||
void esp_wifi_sta_wpa2_ent_clear_new_password(void);
|
||||
|
||||
/**
|
||||
* @brief Set CA certificate for PEAP/TTLS method.
|
||||
*
|
||||
* @attention The API only passes the parameter ca_cert to the global pointer variable in wpa2 enterprise module.
|
||||
* The ca_cert should be zero terminated.
|
||||
*
|
||||
* @param ca_cert: point to address where stores the CA certificate;
|
||||
* len: length of ca_cert
|
||||
*
|
||||
* @return ESP_ERR_WIFI_OK: succeed
|
||||
*/
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_set_ca_cert(unsigned char *ca_cert, int len);
|
||||
|
||||
/**
|
||||
* @brief Clear CA certificate for PEAP/TTLS method.
|
||||
*/
|
||||
void esp_wifi_sta_wpa2_ent_clear_ca_cert(void);
|
||||
|
||||
/**
|
||||
* @brief Set client certificate and key.
|
||||
*
|
||||
* @attention The API only passes the parameter client_cert, private_key and private_key_passwd to the global pointer variable in wpa2 enterprise module.
|
||||
* The client_cert, private_key and private_key_passwd should be zero terminated.
|
||||
*
|
||||
* @param client_cert: point to address where stores the client certificate;
|
||||
* client_cert_len: length of client certificate;
|
||||
* private_key: point to address where stores the private key;
|
||||
* private_key_len: length of private key;
|
||||
* private_key_password: point to address where stores the private key password;
|
||||
* private_key_password_len: length of private key password;
|
||||
*
|
||||
* @return ESP_ERR_WIFI_OK: succeed
|
||||
*/
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_set_cert_key(unsigned char *client_cert, int client_cert_len, unsigned char *private_key, int private_key_len, unsigned char *private_key_passwd, int private_key_passwd_len);
|
||||
|
||||
/**
|
||||
* @brief Clear client certificate and key.
|
||||
*/
|
||||
void esp_wifi_sta_wpa2_ent_clear_cert_key(void);
|
||||
|
||||
/**
|
||||
* @brief Set wpa2 enterprise certs time check(disable or not).
|
||||
*
|
||||
* @param true: disable wpa2 enterprise certs time check
|
||||
* false: enable wpa2 enterprise certs time check
|
||||
*
|
||||
* @return ESP_OK: succeed
|
||||
*/
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_set_disable_time_check(bool disable);
|
||||
|
||||
/**
|
||||
* @brief Get wpa2 enterprise certs time check(disable or not).
|
||||
*
|
||||
* @param disable: store disable value
|
||||
*
|
||||
* @return ESP_OK: succeed
|
||||
*/
|
||||
esp_err_t esp_wifi_sta_wpa2_ent_get_disable_time_check(bool *disable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -1,246 +1,203 @@
|
||||
/*
|
||||
* ESP32 hardware accelerated SHA1/256/512 implementation
|
||||
* based on mbedTLS FIPS-197 compliant version.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE Ltd
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
// Copyright 2015-2016 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.
|
||||
#ifndef _ESP_SHA_H_
|
||||
#define _ESP_SHA_H_
|
||||
|
||||
#include "rom/sha.h"
|
||||
|
||||
#include "esp_types.h"
|
||||
|
||||
/** @brief Low-level support functions for the hardware SHA engine
|
||||
*
|
||||
* @note If you're looking for a SHA API to use, try mbedtls component
|
||||
* mbedtls/shaXX.h. That API supports hardware acceleration.
|
||||
*
|
||||
* The API in this header provides some building blocks for implementing a
|
||||
* full SHA API such as the one in mbedtls, and also a basic SHA function esp_sha().
|
||||
*
|
||||
* Some technical details about the hardware SHA engine:
|
||||
*
|
||||
* - SHA accelerator engine calculates one digest at a time, per SHA
|
||||
* algorithm type. It initialises and maintains the digest state
|
||||
* internally. It is possible to read out an in-progress SHA digest
|
||||
* state, but it is not possible to restore a SHA digest state
|
||||
* into the engine.
|
||||
*
|
||||
* - The memory block SHA_TEXT_BASE is shared between all SHA digest
|
||||
* engines, so all engines must be idle before this memory block is
|
||||
* modified.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief SHA-1 context structure
|
||||
*/
|
||||
typedef struct {
|
||||
/* both types defined in rom/sha.h */
|
||||
SHA_CTX context;
|
||||
enum SHA_TYPE context_type;
|
||||
} esp_sha_context;
|
||||
/* Defined in rom/sha.h */
|
||||
typedef enum SHA_TYPE esp_sha_type;
|
||||
|
||||
/**
|
||||
* \brief Lock access to SHA hardware unit
|
||||
/** @brief Calculate SHA1 or SHA2 sum of some data, using hardware SHA engine
|
||||
*
|
||||
* SHA hardware unit can only be used by one
|
||||
* consumer at a time.
|
||||
* @note For more versatile SHA calculations, where data doesn't need
|
||||
* to be passed all at once, try the mbedTLS mbedtls/shaX.h APIs. The
|
||||
* hardware-accelerated mbedTLS implementation is also faster when
|
||||
* hashing large amounts of data.
|
||||
*
|
||||
* esp_sha_xxx API calls automatically manage locking & unlocking of
|
||||
* hardware, this function is only needed if you want to call
|
||||
* ets_sha_xxx functions directly.
|
||||
*/
|
||||
void esp_sha_acquire_hardware( void );
|
||||
|
||||
/**
|
||||
* \brief Unlock access to SHA hardware unit
|
||||
* @note It is not necessary to lock any SHA hardware before calling
|
||||
* this function, thread safety is managed internally.
|
||||
*
|
||||
* esp_sha_xxx API calls automatically manage locking & unlocking of
|
||||
* hardware, this function is only needed if you want to call
|
||||
* ets_sha_xxx functions directly.
|
||||
*/
|
||||
void esp_sha_release_hardware( void );
|
||||
|
||||
/**
|
||||
* \brief Initialize SHA-1 context
|
||||
* @note If a TLS connection is open then this function may block
|
||||
* indefinitely waiting for a SHA engine to become available. Use the
|
||||
* mbedTLS SHA API to avoid this problem.
|
||||
*
|
||||
* \param ctx SHA-1 context to be initialized
|
||||
*/
|
||||
void esp_sha1_init( esp_sha_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clear SHA-1 context
|
||||
* @param sha_type SHA algorithm to use.
|
||||
*
|
||||
* \param ctx SHA-1 context to be cleared
|
||||
*/
|
||||
void esp_sha1_free( esp_sha_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clone (the state of) a SHA-1 context
|
||||
* @param input Input data buffer.
|
||||
*
|
||||
* \param dst The destination context
|
||||
* \param src The context to be cloned
|
||||
*/
|
||||
void esp_sha1_clone( esp_sha_context *dst, const esp_sha_context *src );
|
||||
|
||||
/**
|
||||
* \brief SHA-1 context setup
|
||||
* @param ilen Length of input data in bytes.
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
* @param output Buffer for output SHA digest. Output is 20 bytes for
|
||||
* sha_type SHA1, 32 bytes for sha_type SHA2_256, 48 bytes for
|
||||
* sha_type SHA2_384, 64 bytes for sha_type SHA2_512.
|
||||
*/
|
||||
void esp_sha1_start( esp_sha_context *ctx );
|
||||
void esp_sha(esp_sha_type sha_type, const unsigned char *input, size_t ilen, unsigned char *output);
|
||||
|
||||
/**
|
||||
* \brief SHA-1 process buffer
|
||||
/* @brief Begin to execute a single SHA block operation
|
||||
*
|
||||
* \param ctx SHA-1 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void esp_sha1_update( esp_sha_context *ctx, const unsigned char *input, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief SHA-1 final digest
|
||||
* @note This is a piece of a SHA algorithm, rather than an entire SHA
|
||||
* algorithm.
|
||||
*
|
||||
* \param ctx SHA-1 context
|
||||
* \param output SHA-1 checksum result
|
||||
*/
|
||||
void esp_sha1_finish( esp_sha_context *ctx, unsigned char output[20] );
|
||||
|
||||
/**
|
||||
* \brief Calculate SHA-1 of input buffer
|
||||
* @note Call esp_sha_try_lock_engine() before calling this
|
||||
* function. Do not call esp_sha_lock_memory_block() beforehand, this
|
||||
* is done inside the function.
|
||||
*
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output SHA-1 checksum result
|
||||
*/
|
||||
void esp_sha1( const unsigned char *input, size_t ilen, unsigned char output[20] );
|
||||
|
||||
/**
|
||||
* \brief SHA-256 context structure
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Initialize SHA-256 context
|
||||
* @param sha_type SHA algorithm to use.
|
||||
*
|
||||
* \param ctx SHA-256 context to be initialized
|
||||
*/
|
||||
void esp_sha256_init( esp_sha_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clear SHA-256 context
|
||||
* @param data_block Pointer to block of data. Block size is
|
||||
* determined by algorithm (SHA1/SHA2_256 = 64 bytes,
|
||||
* SHA2_384/SHA2_512 = 128 bytes)
|
||||
*
|
||||
* \param ctx SHA-256 context to be cleared
|
||||
*/
|
||||
void esp_sha256_free( esp_sha_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clone (the state of) a SHA-256 context
|
||||
* @param is_first_block If this parameter is true, the SHA state will
|
||||
* be initialised (with the initial state of the given SHA algorithm)
|
||||
* before the block is calculated. If false, the existing state of the
|
||||
* SHA engine will be used.
|
||||
*
|
||||
* \param dst The destination context
|
||||
* \param src The context to be cloned
|
||||
* @return As a performance optimisation, this function returns before
|
||||
* the SHA block operation is complete. Both this function and
|
||||
* esp_sha_read_state() will automatically wait for any previous
|
||||
* operation to complete before they begin. If using the SHA registers
|
||||
* directly in another way, call esp_sha_wait_idle() after calling this
|
||||
* function but before accessing the SHA registers.
|
||||
*/
|
||||
void esp_sha256_clone( esp_sha_context *dst, const esp_sha_context *src );
|
||||
void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block);
|
||||
|
||||
/**
|
||||
* \brief SHA-256 context setup
|
||||
/** @brief Read out the current state of the SHA digest loaded in the engine.
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
* \param is224 0 = use SHA256, 1 = use SHA224
|
||||
*/
|
||||
void esp_sha256_start( esp_sha_context *ctx, int is224 );
|
||||
|
||||
/**
|
||||
* \brief SHA-256 process buffer
|
||||
* @note This is a piece of a SHA algorithm, rather than an entire SHA algorithm.
|
||||
*
|
||||
* \param ctx SHA-256 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void esp_sha256_update( esp_sha_context *ctx, const unsigned char *input, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief SHA-256 final digest
|
||||
* @note Call esp_sha_try_lock_engine() before calling this
|
||||
* function. Do not call esp_sha_lock_memory_block() beforehand, this
|
||||
* is done inside the function.
|
||||
*
|
||||
* \param ctx SHA-256 context
|
||||
* \param output SHA-224/256 checksum result
|
||||
*/
|
||||
void esp_sha256_finish( esp_sha_context *ctx, unsigned char output[32] );
|
||||
|
||||
/**
|
||||
* \brief Calculate SHA-256 of input buffer
|
||||
* If the SHA suffix padding block has been executed already, the
|
||||
* value that is read is the SHA digest (in big endian
|
||||
* format). Otherwise, the value that is read is an interim SHA state.
|
||||
*
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output SHA-224/256 checksum result
|
||||
* \param is224 0 = use SHA256, 1 = use SHA224
|
||||
*/
|
||||
void esp_sha256( const unsigned char *input, size_t ilen, unsigned char output[32], int is224 );
|
||||
|
||||
//
|
||||
|
||||
/**
|
||||
* \brief SHA-512 context structure
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Initialize SHA-512 context
|
||||
* @note If sha_type is SHA2_384, only 48 bytes of state will be read.
|
||||
* This is enough for the final SHA2_384 digest, but if you want the
|
||||
* interim SHA-384 state (to continue digesting) then pass SHA2_512 instead.
|
||||
*
|
||||
* @param sha_type SHA algorithm in use.
|
||||
*
|
||||
* @param state Pointer to a memory buffer to hold the SHA state. Size
|
||||
* is 20 bytes (SHA1), 32 bytes (SHA2_256), 48 bytes (SHA2_384) or 64 bytes (SHA2_512).
|
||||
*
|
||||
* \param ctx SHA-512 context to be initialized
|
||||
*/
|
||||
void esp_sha512_init( esp_sha_context *ctx );
|
||||
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state);
|
||||
|
||||
/**
|
||||
* \brief Clear SHA-512 context
|
||||
* @brief Obtain exclusive access to a particular SHA engine
|
||||
*
|
||||
* \param ctx SHA-512 context to be cleared
|
||||
* @param sha_type Type of SHA engine to use.
|
||||
*
|
||||
* Blocks until engine is available. Note: Can block indefinitely
|
||||
* while a TLS connection is open, suggest using
|
||||
* esp_sha_try_lock_engine() and failing over to software SHA.
|
||||
*/
|
||||
void esp_sha512_free( esp_sha_context *ctx );
|
||||
void esp_sha_lock_engine(esp_sha_type sha_type);
|
||||
|
||||
/**
|
||||
* \brief Clone (the state of) a SHA-512 context
|
||||
* @brief Try and obtain exclusive access to a particular SHA engine
|
||||
*
|
||||
* \param dst The destination context
|
||||
* \param src The context to be cloned
|
||||
* @param sha_type Type of SHA engine to use.
|
||||
*
|
||||
* @return Returns true if the SHA engine is locked for exclusive
|
||||
* use. Call esp_sha_unlock_sha_engine() when done. Returns false if
|
||||
* the SHA engine is already in use, caller should use software SHA
|
||||
* algorithm for this digest.
|
||||
*/
|
||||
void esp_sha512_clone( esp_sha_context *dst, const esp_sha_context *src );
|
||||
bool esp_sha_try_lock_engine(esp_sha_type sha_type);
|
||||
|
||||
/**
|
||||
* \brief SHA-512 context setup
|
||||
* @brief Unlock an engine previously locked with esp_sha_lock_engine() or esp_sha_try_lock_engine()
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
* \param is384 0 = use SHA512, 1 = use SHA384
|
||||
* @param sha_type Type of engine to release.
|
||||
*/
|
||||
void esp_sha512_start( esp_sha_context *ctx, int is384 );
|
||||
void esp_sha_unlock_engine(esp_sha_type sha_type);
|
||||
|
||||
/**
|
||||
* \brief SHA-512 process buffer
|
||||
* @brief Acquire exclusive access to the SHA shared memory block at SHA_TEXT_BASE
|
||||
*
|
||||
* \param ctx SHA-512 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* This memory block is shared across all the SHA algorithm types.
|
||||
*
|
||||
* Caller should have already locked a SHA engine before calling this function.
|
||||
*
|
||||
* Note that it is possible to obtain exclusive access to the memory block even
|
||||
* while it is in use by the SHA engine. Caller should use esp_sha_wait_idle()
|
||||
* to ensure the SHA engine is not reading from the memory block in hardware.
|
||||
*
|
||||
* @note You do not need to lock the memory block before calling esp_sha_block() or esp_sha_read_digest_state(), these functions handle memory block locking internally.
|
||||
*
|
||||
* Call esp_sha_unlock_memory_block() when done.
|
||||
*/
|
||||
void esp_sha512_update( esp_sha_context *ctx, const unsigned char *input, size_t ilen );
|
||||
void esp_sha_lock_memory_block(void);
|
||||
|
||||
/**
|
||||
* \brief SHA-512 final digest
|
||||
* @brief Release exclusive access to the SHA register memory block at SHA_TEXT_BASE
|
||||
*
|
||||
* \param ctx SHA-512 context
|
||||
* \param output SHA-384/512 checksum result
|
||||
*/
|
||||
void esp_sha512_finish( esp_sha_context *ctx, unsigned char output[64] );
|
||||
|
||||
/**
|
||||
* \brief Calculate SHA-512 of input buffer.
|
||||
* Caller should have already locked a SHA engine before calling this function.
|
||||
*
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
* \param output SHA-384/512 checksum result
|
||||
* \param is384 0 = use SHA512, 1 = use SHA384
|
||||
* Call following esp_sha_lock_memory_block().
|
||||
*/
|
||||
void esp_sha512( const unsigned char *input, size_t ilen, unsigned char output[64], int is384 );
|
||||
void esp_sha_unlock_memory_block(void);
|
||||
|
||||
//
|
||||
/** @brief Wait for the SHA engine to finish any current operation
|
||||
*
|
||||
* @note This function does not ensure exclusive access to any SHA
|
||||
* engine. Caller should use esp_sha_try_lock_engine() and
|
||||
* esp_sha_lock_memory_block() as required.
|
||||
*
|
||||
* @note Functions declared in this header file wait for SHA engine
|
||||
* completion automatically, so you don't need to use this API for
|
||||
* these. However if accessing SHA registers directly, you will need
|
||||
* to call this before accessing SHA registers if using the
|
||||
* esp_sha_block() function.
|
||||
*
|
||||
* @note This function busy-waits, so wastes CPU resources.
|
||||
* Best to delay calling until you are about to need it.
|
||||
*
|
||||
*/
|
||||
void esp_sha_wait_idle(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -605,6 +605,14 @@ void intr_matrix_set(int cpu_no, uint32_t model_num, uint32_t intr_num);
|
||||
|
||||
#define ETS_MEM_BAR() asm volatile ( "" : : : "memory" )
|
||||
|
||||
typedef enum {
|
||||
OK = 0,
|
||||
FAIL,
|
||||
PENDING,
|
||||
BUSY,
|
||||
CANCEL,
|
||||
} STATUS;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@ -1,9 +1,10 @@
|
||||
/*
|
||||
ROM functions for hardware SHA support.
|
||||
|
||||
It is not recommended to use these functions directly,
|
||||
use the wrapper functions in hwcrypto/sha.h instead.
|
||||
|
||||
It is not recommended to use these functions directly. If using
|
||||
them from esp-idf then use the esp_sha_lock_engine() and
|
||||
esp_sha_lock_memory_block() functions in hwcrypto/sha.h to ensure
|
||||
exclusive access.
|
||||
*/
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
@ -38,6 +39,8 @@ enum SHA_TYPE {
|
||||
SHA2_256,
|
||||
SHA2_384,
|
||||
SHA2_512,
|
||||
|
||||
|
||||
SHA_INVALID = -1,
|
||||
};
|
||||
|
||||
|
@ -384,7 +384,8 @@ SpiFlashOpResult SPIParamCfg(uint32_t deviceId, uint32_t chip_size, uint32_t blo
|
||||
SpiFlashOpResult SPIEraseChip(void);
|
||||
|
||||
/**
|
||||
* @brief Erase a block of flash.
|
||||
* @brief Erase a 32KB block of flash
|
||||
* Uses SPI flash command 52h.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint32_t block_num : Which block to erase.
|
||||
@ -411,6 +412,12 @@ SpiFlashOpResult SPIEraseSector(uint32_t sector_num);
|
||||
* @brief Erase some sectors.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @note If calling this function, first set
|
||||
* g_rom_flashchip.block_size = 32768; or call SPIParamCfg()
|
||||
* with appropriate parameters. This is due to a ROM bug, the
|
||||
* block erase command in use is a 32KB erase but after reset
|
||||
* the block_size field is incorrectly set to 65536.
|
||||
*
|
||||
* @param uint32_t start_addr : Start addr to erase, should be sector aligned.
|
||||
*
|
||||
* @param uint32_t area_len : Length to erase, should be sector aligned.
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "esp_types.h"
|
||||
#include "esp_attr.h"
|
||||
#include "ets_sys.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -51,7 +51,10 @@ static inline void cpu_write_itlb(unsigned vpn, unsigned attr)
|
||||
asm volatile ("witlb %1, %0; isync\n" :: "r" (vpn), "r" (attr));
|
||||
}
|
||||
|
||||
/* Make page 0 access raise an exception.
|
||||
/**
|
||||
* @brief Configure memory region protection
|
||||
*
|
||||
* Make page 0 access raise an exception.
|
||||
* Also protect some other unused pages so we can catch weirdness.
|
||||
* Useful attribute values:
|
||||
* 0 — cached, RW
|
||||
@ -70,9 +73,7 @@ static inline void cpu_configure_region_protection()
|
||||
cpu_write_itlb(0x20000000, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Set CPU frequency to the value defined in menuconfig
|
||||
*
|
||||
* Called from cpu_start.c, not intended to be called from other places.
|
||||
@ -81,4 +82,16 @@ static inline void cpu_configure_region_protection()
|
||||
*/
|
||||
void esp_set_cpu_freq(void);
|
||||
|
||||
/**
|
||||
* @brief Stall CPU using RTC controller
|
||||
* @param cpu_id ID of the CPU to stall (0 = PRO, 1 = APP)
|
||||
*/
|
||||
void esp_cpu_stall(int cpu_id);
|
||||
|
||||
/**
|
||||
* @brief Un-stall CPU using RTC controller
|
||||
* @param cpu_id ID of the CPU to un-stall (0 = PRO, 1 = APP)
|
||||
*/
|
||||
void esp_cpu_unstall(int cpu_id);
|
||||
|
||||
#endif
|
||||
|
@ -94,6 +94,16 @@
|
||||
#define DPORT_PERI_RST_EN_V 0xFFFFFFFF
|
||||
#define DPORT_PERI_RST_EN_S 0
|
||||
|
||||
/* The following bits apply to DPORT_PERI_CLK_EN_REG, DPORT_PERI_RST_EN_REG
|
||||
*/
|
||||
#define DPORT_PERI_EN_AES (1<<0)
|
||||
#define DPORT_PERI_EN_SHA (1<<1)
|
||||
#define DPORT_PERI_EN_RSA (1<<2)
|
||||
/* NB: Secure boot reset will hold SHA & AES in reset */
|
||||
#define DPORT_PERI_EN_SECUREBOOT (1<<3)
|
||||
/* NB: Digital signature reset will hold AES & RSA in reset */
|
||||
#define DPORT_PERI_EN_DIGITAL_SIGNATURE (1<<4)
|
||||
|
||||
#define DPORT_WIFI_BB_CFG_REG (DR_REG_DPORT_BASE + 0x024)
|
||||
/* DPORT_WIFI_BB_CFG : R/W ;bitpos:[31:0] ;default: 32'h0 ; */
|
||||
/*description: */
|
||||
|
@ -30,8 +30,31 @@
|
||||
#define RSA_MULT_MODE_REG (DR_REG_RSA_BASE + 0x80c)
|
||||
#define RSA_MULT_START_REG (DR_REG_RSA_BASE + 0x810)
|
||||
|
||||
#define RSA_INTERRUPT_REG (DR_REG_RSA_BASE + 0X814)
|
||||
#define RSA_INTERRUPT_REG (DR_REG_RSA_BASE + 0x814)
|
||||
|
||||
#define RSA_CLEAN_ADDR (DR_REG_RSA_BASE + 0X818)
|
||||
#define RSA_CLEAN_REG (DR_REG_RSA_BASE + 0x818)
|
||||
|
||||
/* SHA acceleration registers */
|
||||
#define SHA_TEXT_BASE ((DR_REG_SHA_BASE) + 0x00)
|
||||
|
||||
#define SHA_1_START_REG ((DR_REG_SHA_BASE) + 0x80)
|
||||
#define SHA_1_CONTINUE_REG ((DR_REG_SHA_BASE) + 0x84)
|
||||
#define SHA_1_LOAD_REG ((DR_REG_SHA_BASE) + 0x88)
|
||||
#define SHA_1_BUSY_REG ((DR_REG_SHA_BASE) + 0x8c)
|
||||
|
||||
#define SHA_256_START_REG ((DR_REG_SHA_BASE) + 0x90)
|
||||
#define SHA_256_CONTINUE_REG ((DR_REG_SHA_BASE) + 0x94)
|
||||
#define SHA_256_LOAD_REG ((DR_REG_SHA_BASE) + 0x98)
|
||||
#define SHA_256_BUSY_REG ((DR_REG_SHA_BASE) + 0x9c)
|
||||
|
||||
#define SHA_384_START_REG ((DR_REG_SHA_BASE) + 0xa0)
|
||||
#define SHA_384_CONTINUE_REG ((DR_REG_SHA_BASE) + 0xa4)
|
||||
#define SHA_384_LOAD_REG ((DR_REG_SHA_BASE) + 0xa8)
|
||||
#define SHA_384_BUSY_REG ((DR_REG_SHA_BASE) + 0xac)
|
||||
|
||||
#define SHA_512_START_REG ((DR_REG_SHA_BASE) + 0xb0)
|
||||
#define SHA_512_CONTINUE_REG ((DR_REG_SHA_BASE) + 0xb4)
|
||||
#define SHA_512_LOAD_REG ((DR_REG_SHA_BASE) + 0xb8)
|
||||
#define SHA_512_BUSY_REG ((DR_REG_SHA_BASE) + 0xbc)
|
||||
|
||||
#endif
|
||||
|
@ -1319,6 +1319,36 @@
|
||||
#define PCNT_CORE_STATUS_U0_M ((PCNT_CORE_STATUS_U0_V)<<(PCNT_CORE_STATUS_U0_S))
|
||||
#define PCNT_CORE_STATUS_U0_V 0xFFFFFFFF
|
||||
#define PCNT_CORE_STATUS_U0_S 0
|
||||
/*0: positive value to zero; 1: negative value to zero; 2: counter value negative ; 3: counter value positive*/
|
||||
#define PCNT_STATUS_CNT_MODE 0x3
|
||||
#define PCNT_STATUS_CNT_MODE_M ((PCNT_STATUS_CNT_MODE_V)<<(PCNT_STATUS_CNT_MODE_S))
|
||||
#define PCNT_STATUS_CNT_MODE_V 0x3
|
||||
#define PCNT_STATUS_CNT_MODE_S 0
|
||||
/* counter value equals to thresh1*/
|
||||
#define PCNT_STATUS_THRES1 BIT(2)
|
||||
#define PCNT_STATUS_THRES1_M BIT(2)
|
||||
#define PCNT_STATUS_THRES1_V 0x1
|
||||
#define PCNT_STATUS_THRES1_S 2
|
||||
/* counter value equals to thresh0*/
|
||||
#define PCNT_STATUS_THRES0 BIT(3)
|
||||
#define PCNT_STATUS_THRES0_M BIT(3)
|
||||
#define PCNT_STATUS_THRES0_V 0x1
|
||||
#define PCNT_STATUS_THRES0_S 3
|
||||
/* counter value reaches h_lim*/
|
||||
#define PCNT_STATUS_L_LIM BIT(4)
|
||||
#define PCNT_STATUS_L_LIM_M BIT(4)
|
||||
#define PCNT_STATUS_L_LIM_V 0x1
|
||||
#define PCNT_STATUS_L_LIM_S 4
|
||||
/* counter value reaches l_lim*/
|
||||
#define PCNT_STATUS_H_LIM BIT(5)
|
||||
#define PCNT_STATUS_H_LIM_M BIT(5)
|
||||
#define PCNT_STATUS_H_LIM_V 0x1
|
||||
#define PCNT_STATUS_H_LIM_S 5
|
||||
/* counter value equals to zero*/
|
||||
#define PCNT_STATUS_ZERO BIT(6)
|
||||
#define PCNT_STATUS_ZERO_M BIT(6)
|
||||
#define PCNT_STATUS_ZERO_V 0x1
|
||||
#define PCNT_STATUS_ZERO_S 6
|
||||
|
||||
#define PCNT_U1_STATUS_REG (DR_REG_PCNT_BASE + 0x0094)
|
||||
/* PCNT_CORE_STATUS_U1 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
|
||||
|
@ -113,7 +113,18 @@ typedef volatile struct {
|
||||
};
|
||||
uint32_t val;
|
||||
} int_clr;
|
||||
uint32_t status_unit[8];
|
||||
union {
|
||||
struct {
|
||||
uint32_t cnt_mode:2; /*0: positive value to zero; 1: negative value to zero; 2: counter value negative ; 3: counter value positive*/
|
||||
uint32_t thres1_lat:1; /* counter value equals to thresh1*/
|
||||
uint32_t thres0_lat:1; /* counter value equals to thresh0*/
|
||||
uint32_t l_lim_lat:1; /* counter value reaches h_lim*/
|
||||
uint32_t h_lim_lat:1; /* counter value reaches l_lim*/
|
||||
uint32_t zero_lat:1; /* counter value equals zero*/
|
||||
uint32_t reserved7:25;
|
||||
};
|
||||
uint32_t val;
|
||||
} status_unit[8];
|
||||
union {
|
||||
struct {
|
||||
uint32_t cnt_rst_u0: 1; /*Set this bit to clear unit0's counter.*/
|
||||
|
@ -129,10 +129,10 @@
|
||||
//}}
|
||||
|
||||
//Periheral Clock {{
|
||||
#define APB_CLK_FREQ_ROM 26*1000000
|
||||
#define APB_CLK_FREQ_ROM ( 26*1000000 )
|
||||
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
|
||||
#define CPU_CLK_FREQ APB_CLK_FREQ
|
||||
#define APB_CLK_FREQ 80*1000000 //unit: Hz
|
||||
#define APB_CLK_FREQ ( 80*1000000 ) //unit: Hz
|
||||
#define UART_CLK_FREQ APB_CLK_FREQ
|
||||
#define WDT_CLK_FREQ APB_CLK_FREQ
|
||||
#define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 16
|
||||
@ -142,6 +142,7 @@
|
||||
|
||||
#define DR_REG_DPORT_BASE 0x3ff00000
|
||||
#define DR_REG_RSA_BASE 0x3ff02000
|
||||
#define DR_REG_SHA_BASE 0x3ff03000
|
||||
#define DR_REG_UART_BASE 0x3ff40000
|
||||
#define DR_REG_SPI1_BASE 0x3ff42000
|
||||
#define DR_REG_SPI0_BASE 0x3ff43000
|
||||
|
18
components/esp32/include/soc/wdev_reg.h
Normal file
18
components/esp32/include/soc/wdev_reg.h
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2010-2016 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
|
||||
|
||||
/* Hardware random number generator register */
|
||||
#define WDEV_RND_REG 0x60035144
|
@ -42,7 +42,7 @@
|
||||
* share the name with the existing functions from hal.h.
|
||||
* Including this header file will define XTHAL_USE_CACHE_MACROS
|
||||
* which directs hal.h not to use the functions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Single-cache-line operations in C-callable inline assembly.
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "esp_freertos_hooks.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "driver/timer.h"
|
||||
|
||||
#include "esp_int_wdt.h"
|
||||
|
||||
@ -85,7 +86,7 @@ void esp_int_wdt_init() {
|
||||
TIMERG1.wdt_feed=1;
|
||||
TIMERG1.wdt_wprotect=0;
|
||||
TIMERG1.int_clr_timers.wdt=1;
|
||||
TIMERG1.int_ena.wdt=1;
|
||||
timer_group_intr_enable(TIMER_GROUP_1, TIMG_WDT_INT_ENA_M);
|
||||
esp_register_freertos_tick_hook(tick_hook);
|
||||
ESP_INTR_DISABLE(WDT_INT_NUM);
|
||||
intr_matrix_set(xPortGetCoreID(), ETS_TG1_WDT_LEVEL_INTR_SOURCE, WDT_INT_NUM);
|
||||
@ -97,4 +98,4 @@ void esp_int_wdt_init() {
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 93fcc0324cd9b4de8ae381a876d371dfd4eff8e3
|
||||
Subproject commit 4ec70a8ac92828d68bd24acbb27fc179817b14ed
|
133
components/esp32/lib_printf.c
Normal file
133
components/esp32/lib_printf.c
Normal file
@ -0,0 +1,133 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
/**
|
||||
* @file lib_printf.c
|
||||
*
|
||||
* This file contains library-specific printf functions
|
||||
* used by WiFi libraries in the `lib` directory.
|
||||
* These function are used to catch any output which gets printed
|
||||
* by libraries, and redirect it to ESP_LOG macros.
|
||||
*
|
||||
* Eventually WiFi libraries will use ESP_LOG functions internally
|
||||
* and these definitions will be removed.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#define VPRINTF_STACK_BUFFER_SIZE 80
|
||||
|
||||
static int lib_printf(const char* tag, const char* format, va_list arg)
|
||||
{
|
||||
char temp[VPRINTF_STACK_BUFFER_SIZE];
|
||||
int len = vsnprintf(temp, sizeof(temp) - 1, format, arg);
|
||||
temp[sizeof(temp) - 1] = 0;
|
||||
int i;
|
||||
for (i = len - 1; i >= 0; --i) {
|
||||
if (temp[i] != '\n' && temp[i] != '\r' && temp[i] != ' ') {
|
||||
break;
|
||||
}
|
||||
temp[i] = 0;
|
||||
}
|
||||
if (i > 0) {
|
||||
ESP_EARLY_LOGI(tag, "%s", temp);
|
||||
}
|
||||
va_end(arg);
|
||||
return len;
|
||||
}
|
||||
|
||||
int phy_printf(const char* format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
int res = lib_printf("phy", format, arg);
|
||||
va_end(arg);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int rtc_printf(const char* format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
int res = lib_printf("rtc", format, arg);
|
||||
va_end(arg);
|
||||
return res;
|
||||
}
|
||||
|
||||
int wpa_printf(const char* format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
int res = lib_printf("wpa", format, arg);
|
||||
va_end(arg);
|
||||
return res;
|
||||
}
|
||||
|
||||
int wpa2_printf(const char* format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
int res = lib_printf("wpa2", format, arg);
|
||||
va_end(arg);
|
||||
return res;
|
||||
}
|
||||
|
||||
int wps_printf(const char* format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
int res = lib_printf("wps", format, arg);
|
||||
va_end(arg);
|
||||
return res;
|
||||
}
|
||||
|
||||
int pp_printf(const char* format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
int res = lib_printf("pp", format, arg);
|
||||
va_end(arg);
|
||||
return res;
|
||||
}
|
||||
|
||||
int sc_printf(const char* format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
int res = lib_printf("smartconfig", format, arg);
|
||||
va_end(arg);
|
||||
return res;
|
||||
}
|
||||
|
||||
int core_printf(const char* format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
int res = lib_printf("core", format, arg);
|
||||
va_end(arg);
|
||||
return res;
|
||||
}
|
||||
|
||||
int net80211_printf(const char* format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
int res = lib_printf("net80211", format, arg);
|
||||
va_end(arg);
|
||||
return res;
|
||||
}
|
@ -27,6 +27,7 @@
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "soc/cpu.h"
|
||||
|
||||
#include "esp_gdbstub.h"
|
||||
#include "esp_panic.h"
|
||||
@ -108,21 +109,10 @@ static const char *edesc[]={
|
||||
void commonErrorHandler(XtExcFrame *frame);
|
||||
|
||||
//The fact that we've panic'ed probably means the other CPU is now running wild, possibly
|
||||
//messing up the serial output, so we kill it here.
|
||||
static void haltOtherCore() {
|
||||
if (xPortGetCoreID()==0) {
|
||||
//Kill app cpu
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_APPCPU_C1_M);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21<<RTC_CNTL_SW_STALL_APPCPU_C1_S);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_APPCPU_C0_M);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, 2<<RTC_CNTL_SW_STALL_APPCPU_C0_S);
|
||||
} else {
|
||||
//Kill pro cpu
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, RTC_CNTL_SW_STALL_PROCPU_C1_M);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_SW_CPU_STALL_REG, 0x21<<RTC_CNTL_SW_STALL_PROCPU_C1_S);
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_STALL_PROCPU_C0_M);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, 2<<RTC_CNTL_SW_STALL_PROCPU_C0_S);
|
||||
}
|
||||
//messing up the serial output, so we stall it here.
|
||||
static void haltOtherCore()
|
||||
{
|
||||
esp_cpu_stall( xPortGetCoreID() == 0 ? 1 : 0 );
|
||||
}
|
||||
|
||||
//Returns true when a debugger is attached using JTAG.
|
||||
|
@ -179,7 +179,7 @@ static esp_err_t load_cal_data_from_nvs_handle(nvs_handle handle,
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
uint8_t sta_mac[6];
|
||||
system_efuse_read_mac(sta_mac);
|
||||
esp_efuse_read_mac(sta_mac);
|
||||
if (memcmp(sta_mac, cal_data_mac, sizeof(sta_mac)) != 0) {
|
||||
ESP_LOGE(TAG, "%s: calibration data MAC check failed: expected " \
|
||||
MACSTR ", found " MACSTR,
|
||||
@ -210,7 +210,7 @@ static esp_err_t store_cal_data_to_nvs_handle(nvs_handle handle,
|
||||
return err;
|
||||
}
|
||||
uint8_t sta_mac[6];
|
||||
system_efuse_read_mac(sta_mac);
|
||||
esp_efuse_read_mac(sta_mac);
|
||||
err = nvs_set_blob(handle, PHY_CAL_MAC_KEY, sta_mac, sizeof(sta_mac));
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
|
142
components/esp32/rtc.h
Normal file
142
components/esp32/rtc.h
Normal file
@ -0,0 +1,142 @@
|
||||
// Copyright 2015-2016 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.
|
||||
|
||||
/**
|
||||
* @file rtc.h
|
||||
* @brief Declarations of APIs provided by librtc.a
|
||||
*
|
||||
* This file is not in the include directory of esp32 component, so it is not
|
||||
* part of the public API. As the source code of librtc.a is gradually moved
|
||||
* into the ESP-IDF, some of these APIs will be exposed to applications.
|
||||
*
|
||||
* For now, only esp_deep_sleep function declared in esp_deepsleep.h
|
||||
* is part of public API.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "soc/soc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum{
|
||||
XTAL_40M = 40,
|
||||
XTAL_26M = 26,
|
||||
XTAL_24M = 24,
|
||||
XTAL_AUTO = 0
|
||||
} xtal_freq_t;
|
||||
|
||||
typedef enum{
|
||||
CPU_XTAL = 0,
|
||||
CPU_80M = 1,
|
||||
CPU_160M = 2,
|
||||
CPU_240M = 3,
|
||||
CPU_2M = 4
|
||||
} cpu_freq_t;
|
||||
|
||||
typedef enum {
|
||||
CALI_RTC_MUX = 0,
|
||||
CALI_8MD256 = 1,
|
||||
CALI_32K_XTAL = 2
|
||||
} cali_clk_t;
|
||||
|
||||
/**
|
||||
* This function must be called to initialize RTC library
|
||||
* @param xtal_freq Frequency of main crystal
|
||||
*/
|
||||
void rtc_init_lite(xtal_freq_t xtal_freq);
|
||||
|
||||
/**
|
||||
* Switch CPU frequency
|
||||
* @param cpu_freq new CPU frequency
|
||||
*/
|
||||
void rtc_set_cpu_freq(cpu_freq_t cpu_freq);
|
||||
|
||||
/**
|
||||
* @brief Return RTC slow clock's period
|
||||
* @param cali_clk clock to calibrate
|
||||
* @param slow_clk_cycles number of slow clock cycles to average
|
||||
* @param xtal_freq chip's main XTAL freq
|
||||
* @return average slow clock period in microseconds, Q13.19 fixed point format
|
||||
*/
|
||||
uint32_t rtc_slowck_cali(cali_clk_t cali_clk, uint32_t slow_clk_cycles);
|
||||
|
||||
/**
|
||||
* @brief Convert from microseconds to slow clock cycles
|
||||
* @param time_in_us_h Time in microseconds, higher 32 bit part
|
||||
* @param time_in_us_l Time in microseconds, lower 32 bit part
|
||||
* @param slow_clk_period Period of slow clock in microseconds, Q13.19 fixed point format (as returned by rtc_slowck_cali).
|
||||
* @param[out] cylces_h output, higher 32 bit part of number of slow clock cycles
|
||||
* @param[out] cycles_l output, lower 32 bit part of number of slow clock cycles
|
||||
*/
|
||||
void rtc_usec2rtc(uint32_t time_in_us_h, uint32_t time_in_us_l, uint32_t slow_clk_period, uint32_t *cylces_h, uint32_t *cycles_l);
|
||||
|
||||
|
||||
#define DEEP_SLEEP_PD_NORMAL BIT(0) /*!< Base deep sleep mode */
|
||||
#define DEEP_SLEEP_PD_RTC_PERIPH BIT(1) /*!< Power down RTC peripherals */
|
||||
#define DEEP_SLEEP_PD_RTC_SLOW_MEM BIT(2) /*!< Power down RTC SLOW memory */
|
||||
#define DEEP_SLEEP_PD_RTC_FAST_MEM BIT(3) /*!< Power down RTC FAST memory */
|
||||
|
||||
/**
|
||||
* @brief Prepare for entering sleep mode
|
||||
* @param deep_slp DEEP_SLEEP_PD_ flags combined with OR (DEEP_SLEEP_PD_NORMAL must be included)
|
||||
* @param cpu_lp_mode for deep sleep, should be 0
|
||||
*/
|
||||
void rtc_slp_prep_lite(uint32_t deep_slp, uint32_t cpu_lp_mode);
|
||||
|
||||
|
||||
#define RTC_EXT_EVENT0_TRIG BIT(0)
|
||||
#define RTC_EXT_EVENT1_TRIG BIT(1)
|
||||
#define RTC_GPIO_TRIG BIT(2)
|
||||
#define RTC_TIMER_EXPIRE BIT(3)
|
||||
#define RTC_SDIO_TRIG BIT(4)
|
||||
#define RTC_MAC_TRIG BIT(5)
|
||||
#define RTC_UART0_TRIG BIT(6)
|
||||
#define RTC_UART1_TRIG BIT(7)
|
||||
#define RTC_TOUCH_TRIG BIT(8)
|
||||
#define RTC_SAR_TRIG BIT(9)
|
||||
#define RTC_BT_TRIG BIT(10)
|
||||
|
||||
|
||||
#define RTC_EXT_EVENT0_TRIG_EN RTC_EXT_EVENT0_TRIG
|
||||
#define RTC_EXT_EVENT1_TRIG_EN RTC_EXT_EVENT1_TRIG
|
||||
#define RTC_GPIO_TRIG_EN RTC_GPIO_TRIG
|
||||
#define RTC_TIMER_EXPIRE_EN RTC_TIMER_EXPIRE
|
||||
#define RTC_SDIO_TRIG_EN RTC_SDIO_TRIG
|
||||
#define RTC_MAC_TRIG_EN RTC_MAC_TRIG
|
||||
#define RTC_UART0_TRIG_EN RTC_UART0_TRIG
|
||||
#define RTC_UART1_TRIG_EN RTC_UART1_TRIG
|
||||
#define RTC_TOUCH_TRIG_EN RTC_TOUCH_TRIG
|
||||
#define RTC_SAR_TRIG_EN RTC_SAR_TRIG
|
||||
#define RTC_BT_TRIG_EN RTC_BT_TRIG
|
||||
|
||||
/**
|
||||
* @brief Enter sleep mode for given number of cycles
|
||||
* @param cycles_h higher 32 bit part of number of slow clock cycles
|
||||
* @param cycles_l lower 32 bit part of number of slow clock cycles
|
||||
* @param wakeup_opt wake up reason to enable (RTC_xxx_EN flags combined with OR)
|
||||
* @param reject_opt reserved, should be 0
|
||||
* @return TBD
|
||||
*/
|
||||
uint32_t rtc_sleep(uint32_t cycles_h, uint32_t cycles_l, uint32_t wakeup_opt, uint32_t reject_opt);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
158
components/esp32/system_api.c
Normal file
158
components/esp32/system_api.c
Normal file
@ -0,0 +1,158 @@
|
||||
// Copyright 2013-2016 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 "esp_system.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_wifi_internal.h"
|
||||
#include "esp_log.h"
|
||||
#include "rom/efuse.h"
|
||||
#include "rom/cache.h"
|
||||
#include "rom/uart.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/cpu.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
|
||||
static const char* TAG = "system_api";
|
||||
|
||||
void system_init()
|
||||
{
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_read_mac(uint8_t* mac)
|
||||
{
|
||||
uint8_t efuse_crc;
|
||||
uint8_t calc_crc;
|
||||
uint32_t mac_low = REG_READ(EFUSE_BLK0_RDATA1_REG);
|
||||
uint32_t mac_high = REG_READ(EFUSE_BLK0_RDATA2_REG);
|
||||
|
||||
mac[0] = mac_high >> 8;
|
||||
mac[1] = mac_high;
|
||||
mac[2] = mac_low >> 24;
|
||||
mac[3] = mac_low >> 16;
|
||||
mac[4] = mac_low >> 8;
|
||||
mac[5] = mac_low;
|
||||
|
||||
efuse_crc = mac_high >> 16;
|
||||
calc_crc = esp_crc8(mac, 6);
|
||||
|
||||
if (efuse_crc != calc_crc) {
|
||||
// Small range of MAC addresses are accepted even if CRC is invalid.
|
||||
// These addresses are reserved for Espressif internal use.
|
||||
if ((mac_high & 0xFFFF) == 0x18fe) {
|
||||
if ((mac_low >= 0x346a85c7) && (mac_low <= 0x346a85f8)) {
|
||||
return ESP_OK;
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "MAC address CRC error, efuse_crc = 0x%02x; calc_crc = 0x%02x", efuse_crc, calc_crc);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t system_efuse_read_mac(uint8_t mac[6]) __attribute__((alias("esp_efuse_read_mac")));
|
||||
|
||||
|
||||
void IRAM_ATTR esp_restart(void)
|
||||
{
|
||||
esp_wifi_stop();
|
||||
|
||||
// Disable scheduler on this core.
|
||||
vTaskSuspendAll();
|
||||
const uint32_t core_id = xPortGetCoreID();
|
||||
const uint32_t other_core_id = core_id == 0 ? 1 : 0;
|
||||
esp_cpu_stall(other_core_id);
|
||||
|
||||
// We need to disable TG0/TG1 watchdogs
|
||||
// First enable RTC watchdog to be on the safe side
|
||||
REG_WRITE(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
|
||||
REG_WRITE(RTC_CNTL_WDTCONFIG0_REG,
|
||||
RTC_CNTL_WDT_FLASHBOOT_MOD_EN_M |
|
||||
(1 << RTC_CNTL_WDT_SYS_RESET_LENGTH_S) |
|
||||
(1 << RTC_CNTL_WDT_CPU_RESET_LENGTH_S) );
|
||||
REG_WRITE(RTC_CNTL_WDTCONFIG1_REG, 128000);
|
||||
|
||||
// Disable TG0/TG1 watchdogs
|
||||
TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
|
||||
TIMERG0.wdt_config0.en = 0;
|
||||
TIMERG0.wdt_wprotect=0;
|
||||
TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
|
||||
TIMERG1.wdt_config0.en = 0;
|
||||
TIMERG1.wdt_wprotect=0;
|
||||
|
||||
// Disable all interrupts
|
||||
xt_ints_off(0xFFFFFFFF);
|
||||
|
||||
// Disable cache
|
||||
Cache_Read_Disable(0);
|
||||
Cache_Read_Disable(1);
|
||||
|
||||
// Flush any data left in UART FIFO
|
||||
uart_tx_flush(0);
|
||||
uart_tx_flush(1);
|
||||
uart_tx_flush(2);
|
||||
|
||||
// Reset wifi/bluetooth (bb/mac)
|
||||
SET_PERI_REG_MASK(DPORT_WIFI_RST_EN_REG, 0x1f);
|
||||
REG_WRITE(DPORT_WIFI_RST_EN_REG, 0);
|
||||
|
||||
// Reset timer/spi/uart
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,
|
||||
DPORT_TIMERS_RST | DPORT_SPI_RST_1 | DPORT_UART_RST);
|
||||
REG_WRITE(DPORT_PERIP_RST_EN_REG, 0);
|
||||
|
||||
// Reset CPUs
|
||||
if (core_id == 0) {
|
||||
// Running on PRO CPU: APP CPU is stalled. Can reset both CPUs.
|
||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG,
|
||||
RTC_CNTL_SW_PROCPU_RST_M | RTC_CNTL_SW_APPCPU_RST_M);
|
||||
} else {
|
||||
// Running on APP CPU: need to reset PRO CPU and unstall it,
|
||||
// then stall APP CPU
|
||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_PROCPU_RST_M);
|
||||
esp_cpu_unstall(0);
|
||||
esp_cpu_stall(1);
|
||||
}
|
||||
while(true) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void system_restart(void) __attribute__((alias("esp_restart")));
|
||||
|
||||
void system_restore(void)
|
||||
{
|
||||
esp_wifi_restore();
|
||||
}
|
||||
|
||||
uint32_t esp_get_free_heap_size(void)
|
||||
{
|
||||
return xPortGetFreeHeapSize();
|
||||
}
|
||||
|
||||
uint32_t system_get_free_heap_size(void) __attribute__((alias("esp_get_free_heap_size")));
|
||||
|
||||
const char* system_get_sdk_version(void)
|
||||
{
|
||||
return "master";
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/timer.h"
|
||||
|
||||
#include "esp_task_wdt.h"
|
||||
|
||||
@ -204,9 +205,9 @@ void esp_task_wdt_init() {
|
||||
intr_matrix_set(xPortGetCoreID(), ETS_TG0_WDT_LEVEL_INTR_SOURCE, ETS_T0_WDT_INUM);
|
||||
xt_set_interrupt_handler(ETS_T0_WDT_INUM, task_wdt_isr, NULL);
|
||||
TIMERG0.int_clr_timers.wdt=1;
|
||||
TIMERG0.int_ena.wdt=1;
|
||||
timer_group_intr_enable(TIMER_GROUP_0, TIMG_WDT_INT_ENA_M);
|
||||
ESP_INTR_ENABLE(ETS_T0_WDT_INUM);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,9 +0,0 @@
|
||||
menu "TESTS"
|
||||
|
||||
config FP_TEST_ENABLE
|
||||
bool "Enable test fp"
|
||||
default "y"
|
||||
help
|
||||
For FPGA single core CPU which has no floating point support, floating point test should be disabled.
|
||||
|
||||
endmenu
|
@ -4,7 +4,6 @@
|
||||
#include "freertos/task.h"
|
||||
#include "unity.h"
|
||||
|
||||
#if CONFIG_FP_TEST_ENABLE
|
||||
static float addsf(float a, float b)
|
||||
{
|
||||
float result;
|
||||
@ -192,4 +191,3 @@ TEST_CASE("context switch saves FP registers", "[fp]")
|
||||
}
|
||||
TEST_ASSERT(state.fail == 0);
|
||||
}
|
||||
#endif
|
||||
|
@ -609,9 +609,9 @@ void *xRingbufferReceiveUpToFromISR(RingbufHandle_t ringbuf, size_t *item_size,
|
||||
void vRingbufferReturnItem(RingbufHandle_t ringbuf, void *item)
|
||||
{
|
||||
ringbuf_t *rb=(ringbuf_t *)ringbuf;
|
||||
portENTER_CRITICAL_ISR(&rb->mux);
|
||||
portENTER_CRITICAL(&rb->mux);
|
||||
rb->returnItemToRingbufImpl(rb, item);
|
||||
portEXIT_CRITICAL_ISR(&rb->mux);
|
||||
portEXIT_CRITICAL(&rb->mux);
|
||||
xSemaphoreGive(rb->free_space_sem);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@ Config: {execute count: 1, execute order: in order}
|
||||
DUT: [UT1]
|
||||
Filter:
|
||||
- Add:
|
||||
ID: [SYS_OS_0102, SYS_MISC_0103, SYS_MISC_0102, SYS_MISC_0105, SYS_MISC_0104,
|
||||
SYS_MISC_0107, SYS_MISC_0106, SYS_MISC_0109, SYS_MISC_0108, SYS_MISC_0112, SYS_MISC_0113,
|
||||
SYS_MISC_0110, SYS_MISC_0111, SYS_MISC_0115, SYS_LIB_0103, SYS_LIB_0102, SYS_LIB_0101,
|
||||
SYS_LIB_0106, SYS_LIB_0105, SYS_LIB_0104]
|
||||
ID: [SYS_OS_0102, SYS_MISC_0102, SYS_MISC_0107, SYS_MISC_0106, SYS_MISC_0109,
|
||||
SYS_MISC_0108, SYS_MISC_0112, SYS_MISC_0113, SYS_MISC_0110, SYS_MISC_0111, SYS_LIB_0103,
|
||||
SYS_LIB_0102, SYS_LIB_0101, SYS_LIB_0106, SYS_LIB_0105, SYS_LIB_0104]
|
||||
|
@ -18,10 +18,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
#include <rom/ets_sys.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -128,6 +128,7 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
|
||||
|
||||
len = q->tot_len;
|
||||
if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) {
|
||||
ESP_STATS_INC(esp.rx_rawmbox_post_fail);
|
||||
netbuf_delete(buf);
|
||||
return 0;
|
||||
} else {
|
||||
@ -203,6 +204,7 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
|
||||
|
||||
len = p->tot_len;
|
||||
if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) {
|
||||
ESP_STATS_INC(esp.rx_udpmbox_post_fail);
|
||||
netbuf_delete(buf);
|
||||
return;
|
||||
} else {
|
||||
@ -262,6 +264,7 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
|
||||
}
|
||||
|
||||
if (sys_mbox_trypost(&conn->recvmbox, p) != ERR_OK) {
|
||||
ESP_STATS_INC(esp.rx_tcpmbox_post_fail);
|
||||
/* don't deallocate p: it is presented to us later again from tcp_fasttmr! */
|
||||
return ERR_MEM;
|
||||
} else {
|
||||
@ -391,12 +394,16 @@ err_tcp(void *arg, err_t err)
|
||||
/* pass NULL-message to recvmbox to wake up pending recv */
|
||||
if (sys_mbox_valid(&conn->recvmbox)) {
|
||||
/* use trypost to prevent deadlock */
|
||||
sys_mbox_trypost(&conn->recvmbox, NULL);
|
||||
if (sys_mbox_trypost(&conn->recvmbox, NULL) != ERR_OK){
|
||||
ESP_STATS_INC(esp.err_tcp_rxmbox_post_fail);
|
||||
}
|
||||
}
|
||||
/* pass NULL-message to acceptmbox to wake up pending accept */
|
||||
if (sys_mbox_valid(&conn->acceptmbox)) {
|
||||
/* use trypost to preven deadlock */
|
||||
sys_mbox_trypost(&conn->acceptmbox, NULL);
|
||||
if (sys_mbox_trypost(&conn->acceptmbox, NULL) != ERR_OK) {
|
||||
ESP_STATS_INC(esp.err_tcp_rxmbox_post_fail);
|
||||
}
|
||||
}
|
||||
|
||||
if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) ||
|
||||
@ -476,6 +483,7 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
|
||||
newconn->last_err = err;
|
||||
|
||||
if (sys_mbox_trypost(&conn->acceptmbox, newconn) != ERR_OK) {
|
||||
ESP_STATS_INC(esp.acceptmbox_post_fail);
|
||||
/* When returning != ERR_OK, the pcb is aborted in tcp_process(),
|
||||
so do nothing here! */
|
||||
/* remove all references to this netconn from the pcb */
|
||||
|
@ -18,6 +18,9 @@
|
||||
#include "lwip/tcp.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "lwip/priv/tcp_priv.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/priv/memp_priv.h"
|
||||
#include "lwip/memp.h"
|
||||
|
||||
#define DBG_LWIP_IP_SHOW(info, ip) printf("%s type=%d ip=%x\n", (info), (ip).type, (ip).u_addr.ip4.addr)
|
||||
#define DBG_LWIP_IP_PCB_SHOW(pcb) \
|
||||
@ -127,3 +130,42 @@ void dbg_lwip_udp_rxtx_show(void)
|
||||
printf("TBC\n");
|
||||
}
|
||||
|
||||
void dbg_lwip_stats_show(void)
|
||||
{
|
||||
TCP_STATS_DISPLAY();
|
||||
UDP_STATS_DISPLAY();
|
||||
ICMP_STATS_DISPLAY();
|
||||
IGMP_STATS_DISPLAY();
|
||||
IP_STATS_DISPLAY();
|
||||
IPFRAG_STATS_DISPLAY();
|
||||
ETHARP_STATS_DISPLAY();
|
||||
LINK_STATS_DISPLAY();
|
||||
MEM_STATS_DISPLAY();
|
||||
SYS_STATS_DISPLAY();
|
||||
IP6_STATS_DISPLAY();
|
||||
ICMP6_STATS_DISPLAY();
|
||||
IP6_FRAG_STATS_DISPLAY();
|
||||
MLD6_STATS_DISPLAY();
|
||||
ND6_STATS_DISPLAY();
|
||||
ESP_STATS_DISPLAY();
|
||||
}
|
||||
|
||||
#if (ESP_CNT_DEBUG == 1)
|
||||
|
||||
uint32_t g_lwip_mem_cnt[MEMP_MAX][2];
|
||||
extern const struct memp_desc * const memp_pools[MEMP_MAX];
|
||||
|
||||
void dbg_lwip_cnt_show(void)
|
||||
{
|
||||
int i=0;
|
||||
|
||||
printf("-----lwip memory counter-----\n");
|
||||
printf("%6s %8s %8s\n", "index", "alloc", "free");
|
||||
for (i=0; i<MEMP_MAX; i++){
|
||||
printf("%6u %8u %8u\n", i, g_lwip_mem_cnt[i][0], g_lwip_mem_cnt[i][1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -56,9 +56,6 @@
|
||||
#define TCPIP_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_TCPIP_MSG_API, name)
|
||||
|
||||
/* global variables */
|
||||
#if ESP_PERF
|
||||
uint32_t g_rx_post_mbox_fail_cnt = 0;
|
||||
#endif
|
||||
static tcpip_init_done_fn tcpip_init_done;
|
||||
static void *tcpip_init_done_arg;
|
||||
static sys_mbox_t mbox;
|
||||
@ -223,9 +220,7 @@ tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
|
||||
msg->msg.inp.netif = inp;
|
||||
msg->msg.inp.input_fn = input_fn;
|
||||
if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
|
||||
#if ESP_PERF
|
||||
g_rx_post_mbox_fail_cnt ++;
|
||||
#endif
|
||||
ESP_STATS_INC(esp.tcpip_inpkt_post_fail);
|
||||
memp_free(MEMP_TCPIP_MSG_INPKT, msg);
|
||||
return ERR_MEM;
|
||||
}
|
||||
@ -282,6 +277,7 @@ tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block)
|
||||
sys_mbox_post(&mbox, msg);
|
||||
} else {
|
||||
if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
|
||||
ESP_STATS_INC(esp.tcpip_cb_post_fail);
|
||||
memp_free(MEMP_TCPIP_MSG_API, msg);
|
||||
return ERR_MEM;
|
||||
}
|
||||
@ -497,8 +493,13 @@ tcpip_init(tcpip_init_done_fn initfunc, void *arg)
|
||||
|
||||
|
||||
#if ESP_LWIP
|
||||
#if ESP_DUAL_CORE
|
||||
sys_thread_t xLwipTaskHandle = 0;
|
||||
xTaskCreatePinnedToCore(tcpip_thread, TCPIP_THREAD_NAME, TCPIP_THREAD_STACKSIZE, NULL, TCPIP_THREAD_PRIO, NULL, 1);
|
||||
#else
|
||||
sys_thread_t xLwipTaskHandle = sys_thread_new(TCPIP_THREAD_NAME
|
||||
, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
|
||||
#endif
|
||||
|
||||
printf("tcpip_task_hdlxxx : %x, prio:%d,stack:%d\n",
|
||||
(u32_t)xLwipTaskHandle,TCPIP_THREAD_PRIO,TCPIP_THREAD_STACKSIZE);
|
||||
|
@ -180,5 +180,23 @@ stats_display(void)
|
||||
}
|
||||
#endif /* LWIP_STATS_DISPLAY */
|
||||
|
||||
#if ESP_STATS
|
||||
void stats_display_esp(struct stats_esp *esp)
|
||||
{
|
||||
LWIP_PLATFORM_DIAG(("\nESP\n\t"));
|
||||
LWIP_PLATFORM_DIAG(("esp.rx_rawmbox_post_fail: %"U32_F"\n\t", (u32_t)esp->rx_rawmbox_post_fail));
|
||||
LWIP_PLATFORM_DIAG(("esp.rx_udpmbox_post_fail: %"U32_F"\n\t", (u32_t)esp->rx_udpmbox_post_fail));
|
||||
LWIP_PLATFORM_DIAG(("esp.rx_tcpmbox_post_fail: %"U32_F"\n\t", (u32_t)esp->rx_tcpmbox_post_fail));
|
||||
LWIP_PLATFORM_DIAG(("esp.err_tcp_rxmbox_post_fail: %"U32_F"\n\t", (u32_t)esp->err_tcp_rxmbox_post_fail));
|
||||
LWIP_PLATFORM_DIAG(("esp.err_tcp_acceptmbox_post_fail: %"U32_F"\n\t", (u32_t)esp->err_tcp_acceptmbox_post_fail));
|
||||
LWIP_PLATFORM_DIAG(("esp.acceptmbox_post_fail: %"U32_F"\n\t", (u32_t)esp->acceptmbox_post_fail));
|
||||
LWIP_PLATFORM_DIAG(("esp.free_mbox_post_fail: %"U32_F"\n\t", (u32_t)esp->free_mbox_post_fail));
|
||||
LWIP_PLATFORM_DIAG(("esp.tcpip_inpkt_post_fail: %"U32_F"\n\t", (u32_t)esp->tcpip_inpkt_post_fail));
|
||||
LWIP_PLATFORM_DIAG(("esp.tcpip_cb_post_fail: %"U32_F"\n\t", (u32_t)esp->tcpip_cb_post_fail));
|
||||
LWIP_PLATFORM_DIAG(("esp.wlanif_input_pbuf_fail: %"U32_F"\n\t", (u32_t)esp->wlanif_input_pbuf_fail));
|
||||
LWIP_PLATFORM_DIAG(("esp.wlanif_outut_pbuf_fail: %"U32_F"\n\t", (u32_t)esp->wlanif_outut_pbuf_fail));
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LWIP_STATS */
|
||||
|
||||
|
@ -1389,59 +1389,58 @@ tcp_kill_timewait(void)
|
||||
}
|
||||
|
||||
#if ESP_LWIP
|
||||
/**
|
||||
* Kills the oldest connection that is in FIN_WAIT_2 state.
|
||||
* Called from tcp_alloc() if no more connections are available.
|
||||
*/
|
||||
static void tcp_kill_finwait2(void)
|
||||
{
|
||||
struct tcp_pcb *pcb, *inactive;
|
||||
u32_t inactivity;
|
||||
/* Go through the list of FIN_WAIT_2 pcbs and get the oldest pcb. */
|
||||
inactivity = 0;
|
||||
inactive = NULL;
|
||||
for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
|
||||
if (pcb->state == FIN_WAIT_2) {
|
||||
if ((u32_t) (tcp_ticks - pcb->tmr) >= inactivity) {
|
||||
inactivity = tcp_ticks - pcb->tmr;
|
||||
inactive = pcb;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (inactive != NULL) {
|
||||
tcp_pcb_remove(&tcp_active_pcbs, inactive);
|
||||
memp_free(MEMP_TCP_PCB, inactive);
|
||||
}
|
||||
}
|
||||
typedef struct {
|
||||
u8_t time_wait;
|
||||
u8_t closing;
|
||||
u8_t fin_wait2;
|
||||
u8_t last_ack;
|
||||
u8_t fin_wait1;
|
||||
u8_t listen;
|
||||
u8_t bound;
|
||||
u8_t total;
|
||||
}tcp_pcb_num_t;
|
||||
|
||||
/**
|
||||
* Kills the oldest connection that is in LAST_ACK state.
|
||||
* Called from tcp_alloc() if no more connections are available.
|
||||
*/
|
||||
static void tcp_kill_lastack(void)
|
||||
void tcp_pcb_num_cal(tcp_pcb_num_t *tcp_pcb_num)
|
||||
{
|
||||
struct tcp_pcb *pcb, *inactive;
|
||||
u32_t inactivity;
|
||||
/* Go through the list of LAST_ACK pcbs and get the oldest pcb. */
|
||||
inactivity = 0;
|
||||
inactive = NULL;
|
||||
for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
|
||||
if (pcb->state == LAST_ACK) {
|
||||
if ((u32_t) (tcp_ticks - pcb->tmr) >= inactivity) {
|
||||
inactivity = tcp_ticks - pcb->tmr;
|
||||
inactive = pcb;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (inactive != NULL) {
|
||||
tcp_pcb_remove(&tcp_active_pcbs, inactive);
|
||||
memp_free(MEMP_TCP_PCB, inactive);
|
||||
}
|
||||
struct tcp_pcb_listen *listen;
|
||||
struct tcp_pcb *pcb;
|
||||
|
||||
if (!tcp_pcb_num){
|
||||
return;
|
||||
}
|
||||
|
||||
memset(tcp_pcb_num, 0, sizeof(*tcp_pcb_num));
|
||||
for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
|
||||
tcp_pcb_num->total ++;
|
||||
tcp_pcb_num->time_wait ++;
|
||||
}
|
||||
|
||||
for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next){
|
||||
tcp_pcb_num->total ++;
|
||||
if (pcb->state == FIN_WAIT_2){
|
||||
tcp_pcb_num->fin_wait2 ++;
|
||||
} else if (pcb->state == LAST_ACK) {
|
||||
tcp_pcb_num->last_ack ++;
|
||||
} else if (pcb->state == CLOSING) {
|
||||
tcp_pcb_num->closing ++;
|
||||
} else if (pcb->state == FIN_WAIT_1){
|
||||
tcp_pcb_num->fin_wait1 ++;
|
||||
}
|
||||
}
|
||||
|
||||
for (listen = tcp_listen_pcbs.listen_pcbs; listen != NULL; listen = listen->next){
|
||||
tcp_pcb_num->total ++;
|
||||
tcp_pcb_num->listen ++;
|
||||
}
|
||||
|
||||
for (pcb = tcp_bound_pcbs; pcb != NULL; pcb = pcb->next){
|
||||
tcp_pcb_num->total ++;
|
||||
tcp_pcb_num->bound ++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Allocate a new tcp_pcb structure.
|
||||
*
|
||||
@ -1455,34 +1454,34 @@ tcp_alloc(u8_t prio)
|
||||
u32_t iss;
|
||||
|
||||
#if ESP_LWIP
|
||||
/*Kills the oldest connection that is in TIME_WAIT state.*/
|
||||
u8_t time_wait_num = 0;
|
||||
for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
|
||||
time_wait_num ++;
|
||||
tcp_pcb_num_t tcp_pcb_num;
|
||||
|
||||
tcp_pcb_num_cal(&tcp_pcb_num);
|
||||
|
||||
if (tcp_pcb_num.total >= MEMP_NUM_TCP_PCB){
|
||||
if (tcp_pcb_num.time_wait > 0){
|
||||
tcp_kill_timewait();
|
||||
} else if (tcp_pcb_num.last_ack > 0){
|
||||
tcp_kill_state(LAST_ACK);
|
||||
} else if (tcp_pcb_num.closing > 0){
|
||||
tcp_kill_state(CLOSING);
|
||||
} else if (tcp_pcb_num.fin_wait2 > 0){
|
||||
tcp_kill_state(FIN_WAIT_2);
|
||||
} else if (tcp_pcb_num.fin_wait1 > 0){
|
||||
tcp_kill_state(FIN_WAIT_1);
|
||||
} else {
|
||||
tcp_kill_prio(prio);
|
||||
}
|
||||
}
|
||||
|
||||
if (time_wait_num >= MEMP_NUM_TCP_PCB)
|
||||
tcp_kill_timewait();
|
||||
|
||||
/*Kills the oldest connection that is in FIN_WAIT_2 state.*/
|
||||
time_wait_num = 0;
|
||||
for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next){
|
||||
if (pcb->state == FIN_WAIT_2)
|
||||
time_wait_num ++;
|
||||
tcp_pcb_num_cal(&tcp_pcb_num);
|
||||
if (tcp_pcb_num.total >= MEMP_NUM_TCP_PCB){
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: no available tcp pcb %d %d %d %d %d %d %d %d\n",
|
||||
tcp_pcb_num.total, tcp_pcb_num.time_wait, tcp_pcb_num.last_ack, tcp_pcb_num.closing,
|
||||
tcp_pcb_num.fin_wait2, tcp_pcb_num.fin_wait1, tcp_pcb_num.listen, tcp_pcb_num.bound));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (time_wait_num >= MEMP_NUM_TCP_PCB)
|
||||
tcp_kill_finwait2();
|
||||
|
||||
/*Kills the oldest connection that is in LAST_ACK state.*/
|
||||
time_wait_num = 0;
|
||||
for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next){
|
||||
if (pcb->state == LAST_ACK)
|
||||
time_wait_num ++;
|
||||
}
|
||||
|
||||
if (time_wait_num >= MEMP_NUM_TCP_PCB)
|
||||
tcp_kill_lastack();
|
||||
#endif
|
||||
|
||||
pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
|
||||
|
@ -176,7 +176,8 @@ tcp_create_segment(struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno,
|
||||
struct tcp_seg *seg;
|
||||
u8_t optlen = LWIP_TCP_OPT_LENGTH(optflags);
|
||||
|
||||
if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) {
|
||||
seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG);
|
||||
if (seg == NULL) {
|
||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_create_segment: no memory.\n"));
|
||||
pbuf_free(p);
|
||||
return NULL;
|
||||
|
@ -20,5 +20,6 @@ void dbg_lwip_tcp_pcb_show(void);
|
||||
void dbg_lwip_udp_pcb_show(void);
|
||||
void dbg_lwip_tcp_rxtx_show(void);
|
||||
void dbg_lwip_udp_rxtx_show(void);
|
||||
void dbg_lwip_mem_cnt_show(void);
|
||||
|
||||
#endif
|
||||
|
@ -71,8 +71,25 @@ extern const struct memp_desc* const memp_pools[MEMP_MAX];
|
||||
#include "lwip/mem.h"
|
||||
|
||||
#define memp_init()
|
||||
#if ESP_CNT_DEBUG
|
||||
static inline void* memp_malloc(int type)
|
||||
{
|
||||
ESP_CNT_MEM_MALLOC_INC(type);
|
||||
return mem_malloc(memp_pools[type]->size);
|
||||
}
|
||||
|
||||
static inline void memp_free(int type, void *mem)
|
||||
{
|
||||
ESP_CNT_MEM_FREE_INC(type);
|
||||
mem_free(mem);
|
||||
}
|
||||
|
||||
//#define memp_malloc(type) mem_malloc(memp_pools[type]->size); ESP_CNT_MEM_MALLOC_INC(type)
|
||||
//#define memp_free(type, mem) mem_free(mem); ESP_CNT_MEM_FREE_INC(type)
|
||||
#else
|
||||
#define memp_malloc(type) mem_malloc(memp_pools[type]->size)
|
||||
#define memp_free(type, mem) mem_free(mem)
|
||||
#endif
|
||||
|
||||
#define LWIP_MEMPOOL_DECLARE(name,num,size,desc) \
|
||||
const struct memp_desc memp_ ## name = { \
|
||||
|
@ -140,6 +140,16 @@ struct memp_desc {
|
||||
#endif /* MEMP_MEM_MALLOC */
|
||||
};
|
||||
|
||||
#if (ESP_CNT_DEBUG == 1)
|
||||
extern uint32_t g_lwip_mem_cnt[MEMP_MAX][2];
|
||||
#define ESP_CNT_MEM_MALLOC_INC(type) g_lwip_mem_cnt[type][0]++
|
||||
#define ESP_CNT_MEM_FREE_INC(type) g_lwip_mem_cnt[type][1]++
|
||||
#else
|
||||
#define ESP_CNT_MEM_MALLOC_INC(type)
|
||||
#define ESP_CNT_MEM_FREE_INC(type)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef LWIP_DEBUG
|
||||
#define DECLARE_LWIP_MEMPOOL_DESC(desc) (desc),
|
||||
#else
|
||||
|
@ -213,6 +213,23 @@ struct stats_mib2_netif_ctrs {
|
||||
u32_t ifouterrors;
|
||||
};
|
||||
|
||||
struct stats_esp {
|
||||
/* mbox post fail stats */
|
||||
u32_t rx_rawmbox_post_fail;
|
||||
u32_t rx_udpmbox_post_fail;
|
||||
u32_t rx_tcpmbox_post_fail;
|
||||
u32_t err_tcp_rxmbox_post_fail;
|
||||
u32_t err_tcp_acceptmbox_post_fail;
|
||||
u32_t acceptmbox_post_fail;
|
||||
u32_t free_mbox_post_fail;
|
||||
u32_t tcpip_inpkt_post_fail;
|
||||
u32_t tcpip_cb_post_fail;
|
||||
|
||||
/* memory malloc/free/failed stats */
|
||||
u32_t wlanif_input_pbuf_fail;
|
||||
u32_t wlanif_outut_pbuf_fail;
|
||||
};
|
||||
|
||||
struct stats_ {
|
||||
#if LINK_STATS
|
||||
struct stats_proto link;
|
||||
@ -265,6 +282,9 @@ struct stats_ {
|
||||
#if MIB2_STATS
|
||||
struct stats_mib2 mib2;
|
||||
#endif
|
||||
#if ESP_STATS
|
||||
struct stats_esp esp;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern struct stats_ lwip_stats;
|
||||
@ -438,6 +458,14 @@ void stats_init(void);
|
||||
#define MIB2_STATS_INC(x)
|
||||
#endif
|
||||
|
||||
#if ESP_STATS
|
||||
#define ESP_STATS_INC(x) STATS_INC(x)
|
||||
#define ESP_STATS_DISPLAY() stats_display_esp(&lwip_stats.esp);
|
||||
#else
|
||||
#define ESP_STATS_INC(x)
|
||||
#define ESP_STATS_DISPLAY()
|
||||
#endif
|
||||
|
||||
/* Display of statistics */
|
||||
#if LWIP_STATS_DISPLAY
|
||||
void stats_display(void);
|
||||
@ -446,6 +474,7 @@ void stats_display_igmp(struct stats_igmp *igmp, const char *name);
|
||||
void stats_display_mem(struct stats_mem *mem, const char *name);
|
||||
void stats_display_memp(struct stats_mem *mem, int index);
|
||||
void stats_display_sys(struct stats_sys *sys);
|
||||
void stats_display_esp(struct stats_esp *esp);
|
||||
#else /* LWIP_STATS_DISPLAY */
|
||||
#define stats_display()
|
||||
#define stats_display_proto(proto, name)
|
||||
@ -453,6 +482,7 @@ void stats_display_sys(struct stats_sys *sys);
|
||||
#define stats_display_mem(mem, name)
|
||||
#define stats_display_memp(mem, index)
|
||||
#define stats_display_sys(sys)
|
||||
#define stats_display_esp(esp)
|
||||
#endif /* LWIP_STATS_DISPLAY */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -379,22 +379,21 @@
|
||||
* The queue size value itself is platform-dependent, but is passed to
|
||||
* sys_mbox_new() when tcpip_init is called.
|
||||
*/
|
||||
#define TCPIP_MBOX_SIZE 16
|
||||
#define TCPIP_MBOX_SIZE 32
|
||||
|
||||
/**
|
||||
* DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a
|
||||
* NETCONN_UDP. The queue size value itself is platform-dependent, but is passed
|
||||
* to sys_mbox_new() when the recvmbox is created.
|
||||
*/
|
||||
#define DEFAULT_UDP_RECVMBOX_SIZE 16
|
||||
#define DEFAULT_UDP_RECVMBOX_SIZE 6
|
||||
|
||||
/**
|
||||
* DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a
|
||||
* NETCONN_TCP. The queue size value itself is platform-dependent, but is passed
|
||||
* to sys_mbox_new() when the recvmbox is created.
|
||||
*/
|
||||
#define DEFAULT_TCP_RECVMBOX_SIZE 16
|
||||
//#define DEFAULT_TCP_RECVMBOX_SIZE 6
|
||||
#define DEFAULT_TCP_RECVMBOX_SIZE 6
|
||||
|
||||
/**
|
||||
* DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections.
|
||||
@ -556,6 +555,7 @@
|
||||
*/
|
||||
#define TCPIP_DEBUG LWIP_DBG_OFF
|
||||
|
||||
|
||||
/* Enable all Espressif-only options */
|
||||
|
||||
#define ESP_LWIP 1
|
||||
@ -571,6 +571,8 @@
|
||||
#define ESP_IP4_ATON 1
|
||||
#define ESP_LIGHT_SLEEP 1
|
||||
#define ESP_L2_TO_L3_COPY CONFIG_L2_TO_L3_COPY
|
||||
#define ESP_CNT_DEBUG 0
|
||||
#define ESP_DUAL_CORE 0
|
||||
|
||||
#define TCP_WND_DEFAULT (4*TCP_MSS)
|
||||
#define TCP_SND_BUF_DEFAULT (2*TCP_MSS)
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "arch/sys_arch.h"
|
||||
#include "lwip/stats.h"
|
||||
|
||||
/* This is the number of threads that can be started with sys_thread_new() */
|
||||
#define SYS_THREAD_MAX 4
|
||||
@ -370,6 +371,7 @@ sys_mbox_free(sys_mbox_t *mbox)
|
||||
if (post_null){
|
||||
LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_mbox_free: post null to mbox\n"));
|
||||
if (sys_mbox_trypost( mbox, NULL) != ERR_OK){
|
||||
ESP_STATS_INC(esp.free_mbox_post_fail);
|
||||
LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_mbox_free: post null mbox fail\n"));
|
||||
} else {
|
||||
post_null = false;
|
||||
|
@ -161,12 +161,9 @@ wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb)
|
||||
goto _exit;
|
||||
|
||||
#if (ESP_L2_TO_L3_COPY == 1)
|
||||
//p = pbuf_alloc(PBUF_IP, len, PBUF_POOL);
|
||||
p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM);
|
||||
if (p == NULL) {
|
||||
#if ESP_PERF
|
||||
g_rx_alloc_pbuf_fail_cnt++;
|
||||
#endif
|
||||
ESP_STATS_INC(esp.wlanif_input_pbuf_fail);
|
||||
esp_wifi_internal_free_rx_buffer(eb);
|
||||
return;
|
||||
}
|
||||
@ -175,9 +172,7 @@ wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb)
|
||||
#else
|
||||
p = pbuf_alloc(PBUF_RAW, len, PBUF_REF);
|
||||
if (p == NULL){
|
||||
#if ESP_PERF
|
||||
g_rx_alloc_pbuf_fail_cnt++;
|
||||
#endif
|
||||
ESP_STATS_INC(esp.wlanif_input_pbuf_fail);
|
||||
return;
|
||||
}
|
||||
p->payload = buffer;
|
||||
@ -241,7 +236,7 @@ wlanif_init(struct netif *netif)
|
||||
* The last argument should be replaced with your link speed, in units
|
||||
* of bits per second.
|
||||
*/
|
||||
NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
|
||||
NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100);
|
||||
|
||||
netif->name[0] = IFNAME0;
|
||||
netif->name[1] = IFNAME1;
|
||||
|
@ -69,4 +69,16 @@ config MBEDTLS_MPI_INTERRUPT_NUM
|
||||
CPU interrupt number for MPI interrupt to connect to. Must be otherwise unused.
|
||||
Eventually this assignment will be handled automatically at runtime.
|
||||
|
||||
config MBEDTLS_HARDWARE_SHA
|
||||
bool "Enable hardware SHA acceleration"
|
||||
default y
|
||||
help
|
||||
Enable hardware accelerated SHA1, SHA256, SHA384 & SHA512 in mbedTLS.
|
||||
|
||||
Due to a hardware limitation, hardware acceleration is only
|
||||
guaranteed if SHA digests are calculated one at a time. If more
|
||||
than one SHA digest is calculated at the same time, only will
|
||||
be calculated fully in hardware and the rest will be calculated
|
||||
(at least partially calculated) in software.
|
||||
|
||||
endmenu
|
||||
|
@ -5,4 +5,3 @@
|
||||
COMPONENT_ADD_INCLUDEDIRS := port/include include
|
||||
|
||||
COMPONENT_SRCDIRS := library port
|
||||
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include "esp_intr.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#include "soc/dport_reg.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
@ -72,7 +74,16 @@ void esp_mpi_acquire_hardware( void )
|
||||
{
|
||||
/* newlib locks lazy initialize on ESP-IDF */
|
||||
_lock_acquire(&mpi_lock);
|
||||
ets_bigint_enable();
|
||||
REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_RSA);
|
||||
/* also clear reset on digital signature, otherwise RSA is held in reset */
|
||||
REG_CLR_BIT(DPORT_PERI_RST_EN_REG,
|
||||
DPORT_PERI_EN_RSA
|
||||
| DPORT_PERI_EN_DIGITAL_SIGNATURE);
|
||||
|
||||
REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
|
||||
|
||||
while(REG_READ(RSA_CLEAN_REG) != 1);
|
||||
|
||||
#ifdef CONFIG_MBEDTLS_MPI_USE_INTERRUPT
|
||||
rsa_isr_initialise();
|
||||
#endif
|
||||
@ -80,7 +91,12 @@ void esp_mpi_acquire_hardware( void )
|
||||
|
||||
void esp_mpi_release_hardware( void )
|
||||
{
|
||||
ets_bigint_disable();
|
||||
REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
|
||||
|
||||
/* don't reset digital signature unit, as this resets AES also */
|
||||
REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_RSA);
|
||||
REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_RSA);
|
||||
|
||||
_lock_release(&mpi_lock);
|
||||
}
|
||||
|
||||
|
395
components/mbedtls/port/esp_sha1.c
Normal file
395
components/mbedtls/port/esp_sha1.c
Normal file
@ -0,0 +1,395 @@
|
||||
/*
|
||||
* SHA-1 implementation with hardware ESP32 support added.
|
||||
* Uses mbedTLS software implementation for failover when concurrent
|
||||
* SHA operations are in use.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* The SHA-1 standard was published by NIST in 1993.
|
||||
*
|
||||
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_SHA1_ALT)
|
||||
|
||||
#include "mbedtls/sha1.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#include "hwcrypto/sha.h"
|
||||
|
||||
/* 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 (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT32_BE
|
||||
#define GET_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
||||
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
||||
| ( (uint32_t) (b)[(i) + 3] ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT32_BE
|
||||
#define PUT_UINT32_BE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif
|
||||
|
||||
void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
|
||||
{
|
||||
if( ctx == NULL )
|
||||
return;
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
|
||||
esp_sha_unlock_engine(SHA1);
|
||||
}
|
||||
mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
|
||||
const mbedtls_sha1_context *src )
|
||||
{
|
||||
*dst = *src;
|
||||
|
||||
if (src->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
|
||||
/* Copy hardware digest state out to cloned state,
|
||||
which will be a software digest.
|
||||
*/
|
||||
esp_sha_read_digest_state(SHA1, dst->state);
|
||||
dst->mode = ESP_MBEDTLS_SHA1_SOFTWARE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SHA-1 context setup
|
||||
*/
|
||||
void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xEFCDAB89;
|
||||
ctx->state[2] = 0x98BADCFE;
|
||||
ctx->state[3] = 0x10325476;
|
||||
ctx->state[4] = 0xC3D2E1F0;
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
|
||||
esp_sha_unlock_engine(SHA1);
|
||||
}
|
||||
ctx->mode = ESP_MBEDTLS_SHA1_UNUSED;
|
||||
}
|
||||
|
||||
static void mbedtls_sha1_software_process( mbedtls_sha1_context *ctx, const unsigned char data[64] );
|
||||
|
||||
void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
|
||||
{
|
||||
bool first_block = false;
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA1_UNUSED) {
|
||||
/* try to use hardware for this digest */
|
||||
if (esp_sha_try_lock_engine(SHA1)) {
|
||||
ctx->mode = ESP_MBEDTLS_SHA1_HARDWARE;
|
||||
first_block = true;
|
||||
} else {
|
||||
ctx->mode = ESP_MBEDTLS_SHA1_SOFTWARE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
|
||||
esp_sha_block(SHA1, data, first_block);
|
||||
} else {
|
||||
mbedtls_sha1_software_process(ctx, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void mbedtls_sha1_software_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
|
||||
{
|
||||
uint32_t temp, W[16], A, B, C, D, E;
|
||||
|
||||
GET_UINT32_BE( W[ 0], data, 0 );
|
||||
GET_UINT32_BE( W[ 1], data, 4 );
|
||||
GET_UINT32_BE( W[ 2], data, 8 );
|
||||
GET_UINT32_BE( W[ 3], data, 12 );
|
||||
GET_UINT32_BE( W[ 4], data, 16 );
|
||||
GET_UINT32_BE( W[ 5], data, 20 );
|
||||
GET_UINT32_BE( W[ 6], data, 24 );
|
||||
GET_UINT32_BE( W[ 7], data, 28 );
|
||||
GET_UINT32_BE( W[ 8], data, 32 );
|
||||
GET_UINT32_BE( W[ 9], data, 36 );
|
||||
GET_UINT32_BE( W[10], data, 40 );
|
||||
GET_UINT32_BE( W[11], data, 44 );
|
||||
GET_UINT32_BE( W[12], data, 48 );
|
||||
GET_UINT32_BE( W[13], data, 52 );
|
||||
GET_UINT32_BE( W[14], data, 56 );
|
||||
GET_UINT32_BE( W[15], data, 60 );
|
||||
|
||||
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
|
||||
|
||||
#define R(t) \
|
||||
( \
|
||||
temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \
|
||||
W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \
|
||||
( W[t & 0x0F] = S(temp,1) ) \
|
||||
)
|
||||
|
||||
#define P(a,b,c,d,e,x) \
|
||||
{ \
|
||||
e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
E = ctx->state[4];
|
||||
|
||||
#define F(x,y,z) (z ^ (x & (y ^ z)))
|
||||
#define K 0x5A827999
|
||||
|
||||
P( A, B, C, D, E, W[0] );
|
||||
P( E, A, B, C, D, W[1] );
|
||||
P( D, E, A, B, C, W[2] );
|
||||
P( C, D, E, A, B, W[3] );
|
||||
P( B, C, D, E, A, W[4] );
|
||||
P( A, B, C, D, E, W[5] );
|
||||
P( E, A, B, C, D, W[6] );
|
||||
P( D, E, A, B, C, W[7] );
|
||||
P( C, D, E, A, B, W[8] );
|
||||
P( B, C, D, E, A, W[9] );
|
||||
P( A, B, C, D, E, W[10] );
|
||||
P( E, A, B, C, D, W[11] );
|
||||
P( D, E, A, B, C, W[12] );
|
||||
P( C, D, E, A, B, W[13] );
|
||||
P( B, C, D, E, A, W[14] );
|
||||
P( A, B, C, D, E, W[15] );
|
||||
P( E, A, B, C, D, R(16) );
|
||||
P( D, E, A, B, C, R(17) );
|
||||
P( C, D, E, A, B, R(18) );
|
||||
P( B, C, D, E, A, R(19) );
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
#define K 0x6ED9EBA1
|
||||
|
||||
P( A, B, C, D, E, R(20) );
|
||||
P( E, A, B, C, D, R(21) );
|
||||
P( D, E, A, B, C, R(22) );
|
||||
P( C, D, E, A, B, R(23) );
|
||||
P( B, C, D, E, A, R(24) );
|
||||
P( A, B, C, D, E, R(25) );
|
||||
P( E, A, B, C, D, R(26) );
|
||||
P( D, E, A, B, C, R(27) );
|
||||
P( C, D, E, A, B, R(28) );
|
||||
P( B, C, D, E, A, R(29) );
|
||||
P( A, B, C, D, E, R(30) );
|
||||
P( E, A, B, C, D, R(31) );
|
||||
P( D, E, A, B, C, R(32) );
|
||||
P( C, D, E, A, B, R(33) );
|
||||
P( B, C, D, E, A, R(34) );
|
||||
P( A, B, C, D, E, R(35) );
|
||||
P( E, A, B, C, D, R(36) );
|
||||
P( D, E, A, B, C, R(37) );
|
||||
P( C, D, E, A, B, R(38) );
|
||||
P( B, C, D, E, A, R(39) );
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define K 0x8F1BBCDC
|
||||
|
||||
P( A, B, C, D, E, R(40) );
|
||||
P( E, A, B, C, D, R(41) );
|
||||
P( D, E, A, B, C, R(42) );
|
||||
P( C, D, E, A, B, R(43) );
|
||||
P( B, C, D, E, A, R(44) );
|
||||
P( A, B, C, D, E, R(45) );
|
||||
P( E, A, B, C, D, R(46) );
|
||||
P( D, E, A, B, C, R(47) );
|
||||
P( C, D, E, A, B, R(48) );
|
||||
P( B, C, D, E, A, R(49) );
|
||||
P( A, B, C, D, E, R(50) );
|
||||
P( E, A, B, C, D, R(51) );
|
||||
P( D, E, A, B, C, R(52) );
|
||||
P( C, D, E, A, B, R(53) );
|
||||
P( B, C, D, E, A, R(54) );
|
||||
P( A, B, C, D, E, R(55) );
|
||||
P( E, A, B, C, D, R(56) );
|
||||
P( D, E, A, B, C, R(57) );
|
||||
P( C, D, E, A, B, R(58) );
|
||||
P( B, C, D, E, A, R(59) );
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
#define K 0xCA62C1D6
|
||||
|
||||
P( A, B, C, D, E, R(60) );
|
||||
P( E, A, B, C, D, R(61) );
|
||||
P( D, E, A, B, C, R(62) );
|
||||
P( C, D, E, A, B, R(63) );
|
||||
P( B, C, D, E, A, R(64) );
|
||||
P( A, B, C, D, E, R(65) );
|
||||
P( E, A, B, C, D, R(66) );
|
||||
P( D, E, A, B, C, R(67) );
|
||||
P( C, D, E, A, B, R(68) );
|
||||
P( B, C, D, E, A, R(69) );
|
||||
P( A, B, C, D, E, R(70) );
|
||||
P( E, A, B, C, D, R(71) );
|
||||
P( D, E, A, B, C, R(72) );
|
||||
P( C, D, E, A, B, R(73) );
|
||||
P( B, C, D, E, A, R(74) );
|
||||
P( A, B, C, D, E, R(75) );
|
||||
P( E, A, B, C, D, R(76) );
|
||||
P( D, E, A, B, C, R(77) );
|
||||
P( C, D, E, A, B, R(78) );
|
||||
P( B, C, D, E, A, R(79) );
|
||||
|
||||
#undef K
|
||||
#undef F
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
ctx->state[4] += E;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-1 process buffer
|
||||
*/
|
||||
void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen )
|
||||
{
|
||||
size_t fill;
|
||||
uint32_t left;
|
||||
|
||||
if( ilen == 0 )
|
||||
return;
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += (uint32_t) ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if( ctx->total[0] < (uint32_t) ilen )
|
||||
ctx->total[1]++;
|
||||
|
||||
if( left && ilen >= fill )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left), input, fill );
|
||||
mbedtls_sha1_process( ctx, ctx->buffer );
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while( ilen >= 64 )
|
||||
{
|
||||
mbedtls_sha1_process( ctx, input );
|
||||
input += 64;
|
||||
ilen -= 64;
|
||||
}
|
||||
|
||||
if( ilen > 0 )
|
||||
memcpy( (void *) (ctx->buffer + left), input, ilen );
|
||||
}
|
||||
|
||||
static const unsigned char sha1_padding[64] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-1 final digest
|
||||
*/
|
||||
void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] )
|
||||
{
|
||||
uint32_t last, padn;
|
||||
uint32_t high, low;
|
||||
unsigned char msglen[8];
|
||||
|
||||
high = ( ctx->total[0] >> 29 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_UINT32_BE( high, msglen, 0 );
|
||||
PUT_UINT32_BE( low, msglen, 4 );
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
|
||||
|
||||
mbedtls_sha1_update( ctx, sha1_padding, padn );
|
||||
mbedtls_sha1_update( ctx, msglen, 8 );
|
||||
|
||||
/* if state is in hardware, read it out */
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA1_HARDWARE) {
|
||||
esp_sha_read_digest_state(SHA1, ctx->state);
|
||||
esp_sha_unlock_engine(SHA1);
|
||||
ctx->mode = ESP_MBEDTLS_SHA1_SOFTWARE;
|
||||
}
|
||||
|
||||
PUT_UINT32_BE( ctx->state[0], output, 0 );
|
||||
PUT_UINT32_BE( ctx->state[1], output, 4 );
|
||||
PUT_UINT32_BE( ctx->state[2], output, 8 );
|
||||
PUT_UINT32_BE( ctx->state[3], output, 12 );
|
||||
PUT_UINT32_BE( ctx->state[4], output, 16 );
|
||||
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SHA1_C && MBEDTLS_SHA1_ALT */
|
367
components/mbedtls/port/esp_sha256.c
Normal file
367
components/mbedtls/port/esp_sha256.c
Normal file
@ -0,0 +1,367 @@
|
||||
/*
|
||||
* SHA-256 implementation with hardware ESP32 support added.
|
||||
* Uses mbedTLS software implementation for failover when concurrent
|
||||
* SHA operations are in use.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
|
||||
*
|
||||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_SHA256_ALT)
|
||||
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#include "hwcrypto/sha.h"
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
static void mbedtls_zeroize( void *v, size_t n ) {
|
||||
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT32_BE
|
||||
#define GET_UINT32_BE(n,b,i) \
|
||||
do { \
|
||||
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
|
||||
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
|
||||
| ( (uint32_t) (b)[(i) + 3] ); \
|
||||
} while( 0 )
|
||||
#endif
|
||||
|
||||
#ifndef PUT_UINT32_BE
|
||||
#define PUT_UINT32_BE(n,b,i) \
|
||||
do { \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) ); \
|
||||
} while( 0 )
|
||||
#endif
|
||||
|
||||
void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( mbedtls_sha256_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
|
||||
{
|
||||
if( ctx == NULL )
|
||||
return;
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
|
||||
esp_sha_unlock_engine(SHA2_256);
|
||||
}
|
||||
mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
|
||||
const mbedtls_sha256_context *src )
|
||||
{
|
||||
*dst = *src;
|
||||
|
||||
if (src->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
|
||||
/* Copy hardware digest state out to cloned state,
|
||||
which will become a software digest.
|
||||
*/
|
||||
esp_sha_read_digest_state(SHA2_256, dst->state);
|
||||
dst->mode = ESP_MBEDTLS_SHA256_SOFTWARE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-256 context setup
|
||||
*/
|
||||
void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 )
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
if( is224 == 0 )
|
||||
{
|
||||
/* SHA-256 */
|
||||
ctx->state[0] = 0x6A09E667;
|
||||
ctx->state[1] = 0xBB67AE85;
|
||||
ctx->state[2] = 0x3C6EF372;
|
||||
ctx->state[3] = 0xA54FF53A;
|
||||
ctx->state[4] = 0x510E527F;
|
||||
ctx->state[5] = 0x9B05688C;
|
||||
ctx->state[6] = 0x1F83D9AB;
|
||||
ctx->state[7] = 0x5BE0CD19;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* SHA-224 */
|
||||
ctx->state[0] = 0xC1059ED8;
|
||||
ctx->state[1] = 0x367CD507;
|
||||
ctx->state[2] = 0x3070DD17;
|
||||
ctx->state[3] = 0xF70E5939;
|
||||
ctx->state[4] = 0xFFC00B31;
|
||||
ctx->state[5] = 0x68581511;
|
||||
ctx->state[6] = 0x64F98FA7;
|
||||
ctx->state[7] = 0xBEFA4FA4;
|
||||
}
|
||||
|
||||
ctx->is224 = is224;
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
|
||||
esp_sha_unlock_engine(SHA2_256);
|
||||
}
|
||||
ctx->mode = ESP_MBEDTLS_SHA256_UNUSED;
|
||||
}
|
||||
|
||||
#if !defined(MBEDTLS_SHA256_PROCESS_ALT)
|
||||
static const uint32_t K[] =
|
||||
{
|
||||
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
|
||||
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
|
||||
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
|
||||
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
|
||||
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
|
||||
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
|
||||
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
|
||||
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
|
||||
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
|
||||
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
|
||||
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
|
||||
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
|
||||
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
|
||||
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
|
||||
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
|
||||
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
|
||||
};
|
||||
|
||||
#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
|
||||
#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
|
||||
|
||||
#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
|
||||
#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
|
||||
|
||||
#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
|
||||
#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
|
||||
|
||||
#define F0(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define F1(x,y,z) (z ^ (x & (y ^ z)))
|
||||
|
||||
#define R(t) \
|
||||
( \
|
||||
W[t] = S1(W[t - 2]) + W[t - 7] + \
|
||||
S0(W[t - 15]) + W[t - 16] \
|
||||
)
|
||||
|
||||
#define P(a,b,c,d,e,f,g,h,x,K) \
|
||||
{ \
|
||||
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
|
||||
temp2 = S2(a) + F0(a,b,c); \
|
||||
d += temp1; h = temp1 + temp2; \
|
||||
}
|
||||
|
||||
static void mbedtls_sha256_software_process( mbedtls_sha256_context *ctx, const unsigned char data[64] );
|
||||
|
||||
void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
|
||||
{
|
||||
bool first_block = false;
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA256_UNUSED) {
|
||||
/* try to use hardware for this digest */
|
||||
if (!ctx->is224 && esp_sha_try_lock_engine(SHA2_256)) {
|
||||
ctx->mode = ESP_MBEDTLS_SHA256_HARDWARE;
|
||||
first_block = true;
|
||||
} else {
|
||||
ctx->mode = ESP_MBEDTLS_SHA256_SOFTWARE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
|
||||
esp_sha_block(SHA2_256, data, first_block);
|
||||
} else {
|
||||
mbedtls_sha256_software_process(ctx, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void mbedtls_sha256_software_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
|
||||
{
|
||||
uint32_t temp1, temp2, W[64];
|
||||
uint32_t A[8];
|
||||
unsigned int i;
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
A[i] = ctx->state[i];
|
||||
|
||||
#if defined(MBEDTLS_SHA256_SMALLER)
|
||||
for( i = 0; i < 64; i++ )
|
||||
{
|
||||
if( i < 16 )
|
||||
GET_UINT32_BE( W[i], data, 4 * i );
|
||||
else
|
||||
R( i );
|
||||
|
||||
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] );
|
||||
|
||||
temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3];
|
||||
A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1;
|
||||
}
|
||||
#else /* MBEDTLS_SHA256_SMALLER */
|
||||
for( i = 0; i < 16; i++ )
|
||||
GET_UINT32_BE( W[i], data, 4 * i );
|
||||
|
||||
for( i = 0; i < 16; i += 8 )
|
||||
{
|
||||
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] );
|
||||
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] );
|
||||
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] );
|
||||
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] );
|
||||
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] );
|
||||
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] );
|
||||
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] );
|
||||
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] );
|
||||
}
|
||||
|
||||
for( i = 16; i < 64; i += 8 )
|
||||
{
|
||||
P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] );
|
||||
P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] );
|
||||
P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] );
|
||||
P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] );
|
||||
P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] );
|
||||
P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] );
|
||||
P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] );
|
||||
P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] );
|
||||
}
|
||||
#endif /* MBEDTLS_SHA256_SMALLER */
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
ctx->state[i] += A[i];
|
||||
}
|
||||
#endif /* !MBEDTLS_SHA256_PROCESS_ALT */
|
||||
|
||||
/*
|
||||
* SHA-256 process buffer
|
||||
*/
|
||||
void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,
|
||||
size_t ilen )
|
||||
{
|
||||
size_t fill;
|
||||
uint32_t left;
|
||||
|
||||
if( ilen == 0 )
|
||||
return;
|
||||
|
||||
left = ctx->total[0] & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += (uint32_t) ilen;
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
|
||||
if( ctx->total[0] < (uint32_t) ilen )
|
||||
ctx->total[1]++;
|
||||
|
||||
if( left && ilen >= fill )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left), input, fill );
|
||||
mbedtls_sha256_process( ctx, ctx->buffer );
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while( ilen >= 64 )
|
||||
{
|
||||
mbedtls_sha256_process( ctx, input );
|
||||
input += 64;
|
||||
ilen -= 64;
|
||||
}
|
||||
|
||||
if( ilen > 0 )
|
||||
memcpy( (void *) (ctx->buffer + left), input, ilen );
|
||||
}
|
||||
|
||||
static const unsigned char sha256_padding[64] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-256 final digest
|
||||
*/
|
||||
void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] )
|
||||
{
|
||||
uint32_t last, padn;
|
||||
uint32_t high, low;
|
||||
unsigned char msglen[8];
|
||||
|
||||
high = ( ctx->total[0] >> 29 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_UINT32_BE( high, msglen, 0 );
|
||||
PUT_UINT32_BE( low, msglen, 4 );
|
||||
|
||||
last = ctx->total[0] & 0x3F;
|
||||
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
|
||||
|
||||
mbedtls_sha256_update( ctx, sha256_padding, padn );
|
||||
mbedtls_sha256_update( ctx, msglen, 8 );
|
||||
|
||||
/* if state is in hardware, read it out */
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA256_HARDWARE) {
|
||||
esp_sha_read_digest_state(SHA2_256, ctx->state);
|
||||
esp_sha_unlock_engine(SHA2_256);
|
||||
ctx->mode = ESP_MBEDTLS_SHA256_SOFTWARE;
|
||||
}
|
||||
|
||||
PUT_UINT32_BE( ctx->state[0], output, 0 );
|
||||
PUT_UINT32_BE( ctx->state[1], output, 4 );
|
||||
PUT_UINT32_BE( ctx->state[2], output, 8 );
|
||||
PUT_UINT32_BE( ctx->state[3], output, 12 );
|
||||
PUT_UINT32_BE( ctx->state[4], output, 16 );
|
||||
PUT_UINT32_BE( ctx->state[5], output, 20 );
|
||||
PUT_UINT32_BE( ctx->state[6], output, 24 );
|
||||
|
||||
if( ctx->is224 == 0 )
|
||||
PUT_UINT32_BE( ctx->state[7], output, 28 );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SHA256_C && MBEDTLS_SHA256_ALT */
|
412
components/mbedtls/port/esp_sha512.c
Normal file
412
components/mbedtls/port/esp_sha512.c
Normal file
@ -0,0 +1,412 @@
|
||||
/*
|
||||
* SHA-512 implementation with hardware ESP32 support added.
|
||||
* Uses mbedTLS software implementation for failover when concurrent
|
||||
* SHA operations are in use.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* The SHA-512 Secure Hash Standard was published by NIST in 2002.
|
||||
*
|
||||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
|
||||
*/
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_SHA512_ALT)
|
||||
|
||||
#include "mbedtls/sha512.h"
|
||||
|
||||
#if defined(_MSC_VER) || defined(__WATCOMC__)
|
||||
#define UL64(x) x##ui64
|
||||
#else
|
||||
#define UL64(x) x##ULL
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_SELF_TEST)
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define mbedtls_printf printf
|
||||
#endif /* MBEDTLS_PLATFORM_C */
|
||||
#endif /* MBEDTLS_SELF_TEST */
|
||||
|
||||
#include "hwcrypto/sha.h"
|
||||
|
||||
inline static esp_sha_type sha_type(const mbedtls_sha512_context *ctx)
|
||||
{
|
||||
return ctx->is384 ? SHA2_384 : SHA2_512;
|
||||
}
|
||||
|
||||
/* Implementation that should never be optimized out by the compiler */
|
||||
static void mbedtls_zeroize( void *v, size_t n ) {
|
||||
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 64-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
#ifndef GET_UINT64_BE
|
||||
#define GET_UINT64_BE(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (uint64_t) (b)[(i) ] << 56 ) \
|
||||
| ( (uint64_t) (b)[(i) + 1] << 48 ) \
|
||||
| ( (uint64_t) (b)[(i) + 2] << 40 ) \
|
||||
| ( (uint64_t) (b)[(i) + 3] << 32 ) \
|
||||
| ( (uint64_t) (b)[(i) + 4] << 24 ) \
|
||||
| ( (uint64_t) (b)[(i) + 5] << 16 ) \
|
||||
| ( (uint64_t) (b)[(i) + 6] << 8 ) \
|
||||
| ( (uint64_t) (b)[(i) + 7] ); \
|
||||
}
|
||||
#endif /* GET_UINT64_BE */
|
||||
|
||||
#ifndef PUT_UINT64_BE
|
||||
#define PUT_UINT64_BE(n,b,i) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
|
||||
(b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
|
||||
(b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
|
||||
(b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
|
||||
(b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
|
||||
(b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
|
||||
(b)[(i) + 7] = (unsigned char) ( (n) ); \
|
||||
}
|
||||
#endif /* PUT_UINT64_BE */
|
||||
|
||||
void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
|
||||
{
|
||||
memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha512_free( mbedtls_sha512_context *ctx )
|
||||
{
|
||||
if( ctx == NULL )
|
||||
return;
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
|
||||
esp_sha_unlock_engine(sha_type(ctx));
|
||||
}
|
||||
mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) );
|
||||
}
|
||||
|
||||
void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
|
||||
const mbedtls_sha512_context *src )
|
||||
{
|
||||
*dst = *src;
|
||||
|
||||
if (src->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
|
||||
/* Copy hardware digest state out to cloned state,
|
||||
which will be a software digest.
|
||||
|
||||
Always read 512 bits of state, even for SHA-384
|
||||
(SHA-384 state is identical to SHA-512, only
|
||||
digest is truncated.)
|
||||
*/
|
||||
esp_sha_read_digest_state(SHA2_512, dst->state);
|
||||
dst->mode = ESP_MBEDTLS_SHA512_SOFTWARE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SHA-512 context setup
|
||||
*/
|
||||
void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
|
||||
if( is384 == 0 )
|
||||
{
|
||||
/* SHA-512 */
|
||||
ctx->state[0] = UL64(0x6A09E667F3BCC908);
|
||||
ctx->state[1] = UL64(0xBB67AE8584CAA73B);
|
||||
ctx->state[2] = UL64(0x3C6EF372FE94F82B);
|
||||
ctx->state[3] = UL64(0xA54FF53A5F1D36F1);
|
||||
ctx->state[4] = UL64(0x510E527FADE682D1);
|
||||
ctx->state[5] = UL64(0x9B05688C2B3E6C1F);
|
||||
ctx->state[6] = UL64(0x1F83D9ABFB41BD6B);
|
||||
ctx->state[7] = UL64(0x5BE0CD19137E2179);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* SHA-384 */
|
||||
ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
|
||||
ctx->state[1] = UL64(0x629A292A367CD507);
|
||||
ctx->state[2] = UL64(0x9159015A3070DD17);
|
||||
ctx->state[3] = UL64(0x152FECD8F70E5939);
|
||||
ctx->state[4] = UL64(0x67332667FFC00B31);
|
||||
ctx->state[5] = UL64(0x8EB44A8768581511);
|
||||
ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
|
||||
ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
|
||||
}
|
||||
|
||||
ctx->is384 = is384;
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
|
||||
esp_sha_unlock_engine(sha_type(ctx));
|
||||
}
|
||||
ctx->mode = ESP_MBEDTLS_SHA512_UNUSED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Round constants
|
||||
*/
|
||||
static const uint64_t K[80] =
|
||||
{
|
||||
UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD),
|
||||
UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC),
|
||||
UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019),
|
||||
UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118),
|
||||
UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE),
|
||||
UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2),
|
||||
UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1),
|
||||
UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694),
|
||||
UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3),
|
||||
UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65),
|
||||
UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483),
|
||||
UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5),
|
||||
UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210),
|
||||
UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4),
|
||||
UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725),
|
||||
UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70),
|
||||
UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926),
|
||||
UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF),
|
||||
UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8),
|
||||
UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B),
|
||||
UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001),
|
||||
UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30),
|
||||
UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910),
|
||||
UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8),
|
||||
UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53),
|
||||
UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8),
|
||||
UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB),
|
||||
UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3),
|
||||
UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60),
|
||||
UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC),
|
||||
UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9),
|
||||
UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B),
|
||||
UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207),
|
||||
UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178),
|
||||
UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6),
|
||||
UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B),
|
||||
UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493),
|
||||
UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C),
|
||||
UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A),
|
||||
UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817)
|
||||
};
|
||||
|
||||
static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const unsigned char data[128] );
|
||||
|
||||
void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
|
||||
{
|
||||
bool first_block = false;
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA512_UNUSED) {
|
||||
/* try to use hardware for this digest */
|
||||
if (esp_sha_try_lock_engine(sha_type(ctx))) {
|
||||
ctx->mode = ESP_MBEDTLS_SHA512_HARDWARE;
|
||||
first_block = true;
|
||||
} else {
|
||||
ctx->mode = ESP_MBEDTLS_SHA512_SOFTWARE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
|
||||
esp_sha_block(sha_type(ctx), data, first_block);
|
||||
} else {
|
||||
mbedtls_sha512_software_process(ctx, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void mbedtls_sha512_software_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
|
||||
{
|
||||
int i;
|
||||
uint64_t temp1, temp2, W[80];
|
||||
uint64_t A, B, C, D, E, F, G, H;
|
||||
|
||||
#define SHR(x,n) (x >> n)
|
||||
#define ROTR(x,n) (SHR(x,n) | (x << (64 - n)))
|
||||
|
||||
#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
|
||||
#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6))
|
||||
|
||||
#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
|
||||
#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
|
||||
|
||||
#define F0(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define F1(x,y,z) (z ^ (x & (y ^ z)))
|
||||
|
||||
#define P(a,b,c,d,e,f,g,h,x,K) \
|
||||
{ \
|
||||
temp1 = h + S3(e) + F1(e,f,g) + K + x; \
|
||||
temp2 = S2(a) + F0(a,b,c); \
|
||||
d += temp1; h = temp1 + temp2; \
|
||||
}
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
GET_UINT64_BE( W[i], data, i << 3 );
|
||||
}
|
||||
|
||||
for( ; i < 80; i++ )
|
||||
{
|
||||
W[i] = S1(W[i - 2]) + W[i - 7] +
|
||||
S0(W[i - 15]) + W[i - 16];
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
E = ctx->state[4];
|
||||
F = ctx->state[5];
|
||||
G = ctx->state[6];
|
||||
H = ctx->state[7];
|
||||
i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++;
|
||||
P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++;
|
||||
P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++;
|
||||
P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++;
|
||||
P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++;
|
||||
P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++;
|
||||
P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++;
|
||||
P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++;
|
||||
}
|
||||
while( i < 80 );
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
ctx->state[4] += E;
|
||||
ctx->state[5] += F;
|
||||
ctx->state[6] += G;
|
||||
ctx->state[7] += H;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-512 process buffer
|
||||
*/
|
||||
void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,
|
||||
size_t ilen )
|
||||
{
|
||||
size_t fill;
|
||||
unsigned int left;
|
||||
|
||||
if( ilen == 0 )
|
||||
return;
|
||||
|
||||
left = (unsigned int) (ctx->total[0] & 0x7F);
|
||||
fill = 128 - left;
|
||||
|
||||
ctx->total[0] += (uint64_t) ilen;
|
||||
|
||||
if( ctx->total[0] < (uint64_t) ilen )
|
||||
ctx->total[1]++;
|
||||
|
||||
if( left && ilen >= fill )
|
||||
{
|
||||
memcpy( (void *) (ctx->buffer + left), input, fill );
|
||||
mbedtls_sha512_process( ctx, ctx->buffer );
|
||||
input += fill;
|
||||
ilen -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while( ilen >= 128 )
|
||||
{
|
||||
mbedtls_sha512_process( ctx, input );
|
||||
input += 128;
|
||||
ilen -= 128;
|
||||
}
|
||||
|
||||
if( ilen > 0 )
|
||||
memcpy( (void *) (ctx->buffer + left), input, ilen );
|
||||
}
|
||||
|
||||
static const unsigned char sha512_padding[128] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* SHA-512 final digest
|
||||
*/
|
||||
void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64] )
|
||||
{
|
||||
size_t last, padn;
|
||||
uint64_t high, low;
|
||||
unsigned char msglen[16];
|
||||
|
||||
high = ( ctx->total[0] >> 61 )
|
||||
| ( ctx->total[1] << 3 );
|
||||
low = ( ctx->total[0] << 3 );
|
||||
|
||||
PUT_UINT64_BE( high, msglen, 0 );
|
||||
PUT_UINT64_BE( low, msglen, 8 );
|
||||
|
||||
last = (size_t)( ctx->total[0] & 0x7F );
|
||||
padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
|
||||
|
||||
mbedtls_sha512_update( ctx, sha512_padding, padn );
|
||||
mbedtls_sha512_update( ctx, msglen, 16 );
|
||||
|
||||
/* if state is in hardware, read it out */
|
||||
if (ctx->mode == ESP_MBEDTLS_SHA512_HARDWARE) {
|
||||
esp_sha_read_digest_state(sha_type(ctx), ctx->state);
|
||||
esp_sha_unlock_engine(sha_type(ctx));
|
||||
ctx->mode = ESP_MBEDTLS_SHA512_SOFTWARE;
|
||||
}
|
||||
|
||||
PUT_UINT64_BE( ctx->state[0], output, 0 );
|
||||
PUT_UINT64_BE( ctx->state[1], output, 8 );
|
||||
PUT_UINT64_BE( ctx->state[2], output, 16 );
|
||||
PUT_UINT64_BE( ctx->state[3], output, 24 );
|
||||
PUT_UINT64_BE( ctx->state[4], output, 32 );
|
||||
PUT_UINT64_BE( ctx->state[5], output, 40 );
|
||||
|
||||
if( ctx->is384 == 0 )
|
||||
{
|
||||
PUT_UINT64_BE( ctx->state[6], output, 48 );
|
||||
PUT_UINT64_BE( ctx->state[7], output, 56 );
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_SHA512_C && MBEDTLS_SHA512_ALT */
|
@ -243,11 +243,14 @@
|
||||
#define MBEDTLS_AES_ALT
|
||||
#endif
|
||||
|
||||
/* Currently hardware SHA does not work with TLS handshake,
|
||||
due to concurrency issue. Internal TW#7111. */
|
||||
//#define MBEDTLS_SHA1_ALT
|
||||
//#define MBEDTLS_SHA256_ALT
|
||||
//#define MBEDTLS_SHA512_ALT
|
||||
/* MBEDTLS_SHAxx_ALT to enable hardware SHA support
|
||||
with software fallback.
|
||||
*/
|
||||
#ifdef CONFIG_MBEDTLS_HARDWARE_SHA
|
||||
#define MBEDTLS_SHA1_ALT
|
||||
#define MBEDTLS_SHA256_ALT
|
||||
#define MBEDTLS_SHA512_ALT
|
||||
#endif
|
||||
|
||||
/* The following MPI (bignum) functions have ESP32 hardware support,
|
||||
Uncommenting these macros will use the hardware-accelerated
|
||||
|
@ -1,16 +1,25 @@
|
||||
// Copyright 2015-2016 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.
|
||||
/*
|
||||
* SHA-1 implementation with hardware ESP32 support added.
|
||||
* Uses mbedTLS software implementation for failover when concurrent
|
||||
* SHA operations are in use.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
|
||||
* 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 _SHA1_ALT_H_
|
||||
#define _SHA1_ALT_H_
|
||||
|
||||
@ -20,17 +29,73 @@ extern "C" {
|
||||
|
||||
#if defined(MBEDTLS_SHA1_ALT)
|
||||
|
||||
#include "hwcrypto/sha.h"
|
||||
typedef enum {
|
||||
ESP_MBEDTLS_SHA1_UNUSED, /* first block hasn't been processed yet */
|
||||
ESP_MBEDTLS_SHA1_HARDWARE, /* using hardware SHA engine */
|
||||
ESP_MBEDTLS_SHA1_SOFTWARE, /* using software SHA */
|
||||
} esp_mbedtls_sha1_mode;
|
||||
|
||||
typedef esp_sha_context mbedtls_sha1_context;
|
||||
/**
|
||||
* \brief SHA-1 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t total[2]; /*!< number of bytes processed */
|
||||
uint32_t state[5]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
esp_mbedtls_sha1_mode mode;
|
||||
}
|
||||
mbedtls_sha1_context;
|
||||
|
||||
#define mbedtls_sha1_init esp_sha1_init
|
||||
#define mbedtls_sha1_starts esp_sha1_start
|
||||
#define mbedtls_sha1_clone esp_sha1_clone
|
||||
#define mbedtls_sha1_update esp_sha1_update
|
||||
#define mbedtls_sha1_finish esp_sha1_finish
|
||||
#define mbedtls_sha1_free esp_sha1_free
|
||||
#define mbedtls_sha1_process(...)
|
||||
/**
|
||||
* \brief Initialize SHA-1 context
|
||||
*
|
||||
* \param ctx SHA-1 context to be initialized
|
||||
*/
|
||||
void mbedtls_sha1_init( mbedtls_sha1_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clear SHA-1 context
|
||||
*
|
||||
* \param ctx SHA-1 context to be cleared
|
||||
*/
|
||||
void mbedtls_sha1_free( mbedtls_sha1_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clone (the state of) a SHA-1 context
|
||||
*
|
||||
* \param dst The destination context
|
||||
* \param src The context to be cloned
|
||||
*/
|
||||
void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
|
||||
const mbedtls_sha1_context *src );
|
||||
|
||||
/**
|
||||
* \brief SHA-1 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
*/
|
||||
void mbedtls_sha1_starts( mbedtls_sha1_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief SHA-1 process buffer
|
||||
*
|
||||
* \param ctx SHA-1 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief SHA-1 final digest
|
||||
*
|
||||
* \param ctx SHA-1 context
|
||||
* \param output SHA-1 checksum result
|
||||
*/
|
||||
void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] );
|
||||
|
||||
/* Internal use */
|
||||
void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] );
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,16 +1,25 @@
|
||||
// Copyright 2015-2016 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.
|
||||
/*
|
||||
* SHA-256 implementation with hardware ESP32 support added.
|
||||
* Uses mbedTLS software implementation for failover when concurrent
|
||||
* SHA operations are in use.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
|
||||
* 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 _SHA256_ALT_H_
|
||||
#define _SHA256_ALT_H_
|
||||
|
||||
@ -20,17 +29,76 @@ extern "C" {
|
||||
|
||||
#if defined(MBEDTLS_SHA256_ALT)
|
||||
|
||||
#include "hwcrypto/sha.h"
|
||||
typedef enum {
|
||||
ESP_MBEDTLS_SHA256_UNUSED, /* first block hasn't been processed yet */
|
||||
ESP_MBEDTLS_SHA256_HARDWARE, /* using hardware SHA engine */
|
||||
ESP_MBEDTLS_SHA256_SOFTWARE, /* using software SHA */
|
||||
} esp_mbedtls_sha256_mode;
|
||||
|
||||
typedef esp_sha_context mbedtls_sha256_context;
|
||||
/**
|
||||
* \brief SHA-256 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t total[2]; /*!< number of bytes processed */
|
||||
uint32_t state[8]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
int is224; /*!< 0 => SHA-256, else SHA-224 */
|
||||
esp_mbedtls_sha256_mode mode;
|
||||
}
|
||||
mbedtls_sha256_context;
|
||||
|
||||
#define mbedtls_sha256_init esp_sha256_init
|
||||
#define mbedtls_sha256_clone esp_sha256_clone
|
||||
#define mbedtls_sha256_starts esp_sha256_start
|
||||
#define mbedtls_sha256_update esp_sha256_update
|
||||
#define mbedtls_sha256_finish esp_sha256_finish
|
||||
#define mbedtls_sha256_free esp_sha256_free
|
||||
#define mbedtls_sha256_process(...)
|
||||
/**
|
||||
* \brief Initialize SHA-256 context
|
||||
*
|
||||
* \param ctx SHA-256 context to be initialized
|
||||
*/
|
||||
void mbedtls_sha256_init( mbedtls_sha256_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clear SHA-256 context
|
||||
*
|
||||
* \param ctx SHA-256 context to be cleared
|
||||
*/
|
||||
void mbedtls_sha256_free( mbedtls_sha256_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clone (the state of) a SHA-256 context
|
||||
*
|
||||
* \param dst The destination context
|
||||
* \param src The context to be cloned
|
||||
*/
|
||||
void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
|
||||
const mbedtls_sha256_context *src );
|
||||
|
||||
/**
|
||||
* \brief SHA-256 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
* \param is224 0 = use SHA256, 1 = use SHA224
|
||||
*/
|
||||
void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 );
|
||||
|
||||
/**
|
||||
* \brief SHA-256 process buffer
|
||||
*
|
||||
* \param ctx SHA-256 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input,
|
||||
size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief SHA-256 final digest
|
||||
*
|
||||
* \param ctx SHA-256 context
|
||||
* \param output SHA-224/256 checksum result
|
||||
*/
|
||||
void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] );
|
||||
|
||||
/* Internal use */
|
||||
void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] );
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,16 +1,25 @@
|
||||
// Copyright 2015-2016 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.
|
||||
/*
|
||||
* SHA-512 implementation with hardware ESP32 support added.
|
||||
* Uses mbedTLS software implementation for failover when concurrent
|
||||
* SHA operations are in use.
|
||||
*
|
||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||
* Additions Copyright (C) 2016, Espressif Systems (Shanghai) PTE LTD
|
||||
* 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 _SHA512_ALT_H_
|
||||
#define _SHA512_ALT_H_
|
||||
|
||||
@ -19,17 +28,77 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SHA512_ALT)
|
||||
#include "hwcrypto/sha.h"
|
||||
|
||||
typedef esp_sha_context mbedtls_sha512_context;
|
||||
typedef enum {
|
||||
ESP_MBEDTLS_SHA512_UNUSED, /* first block hasn't been processed yet */
|
||||
ESP_MBEDTLS_SHA512_HARDWARE, /* using hardware SHA engine */
|
||||
ESP_MBEDTLS_SHA512_SOFTWARE, /* using software SHA */
|
||||
} esp_mbedtls_sha512_mode;
|
||||
|
||||
#define mbedtls_sha512_init esp_sha512_init
|
||||
#define mbedtls_sha512_clone esp_sha512_clone
|
||||
#define mbedtls_sha512_starts esp_sha512_start
|
||||
#define mbedtls_sha512_update esp_sha512_update
|
||||
#define mbedtls_sha512_finish esp_sha512_finish
|
||||
#define mbedtls_sha512_free esp_sha512_free
|
||||
#define mbedtls_sha512_process(...)
|
||||
/**
|
||||
* \brief SHA-512 context structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint64_t total[2]; /*!< number of bytes processed */
|
||||
uint64_t state[8]; /*!< intermediate digest state */
|
||||
unsigned char buffer[128]; /*!< data block being processed */
|
||||
int is384; /*!< 0 => SHA-512, else SHA-384 */
|
||||
esp_mbedtls_sha512_mode mode;
|
||||
}
|
||||
mbedtls_sha512_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize SHA-512 context
|
||||
*
|
||||
* \param ctx SHA-512 context to be initialized
|
||||
*/
|
||||
void mbedtls_sha512_init( mbedtls_sha512_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clear SHA-512 context
|
||||
*
|
||||
* \param ctx SHA-512 context to be cleared
|
||||
*/
|
||||
void mbedtls_sha512_free( mbedtls_sha512_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clone (the state of) a SHA-512 context
|
||||
*
|
||||
* \param dst The destination context
|
||||
* \param src The context to be cloned
|
||||
*/
|
||||
void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
|
||||
const mbedtls_sha512_context *src );
|
||||
|
||||
/**
|
||||
* \brief SHA-512 context setup
|
||||
*
|
||||
* \param ctx context to be initialized
|
||||
* \param is384 0 = use SHA512, 1 = use SHA384
|
||||
*/
|
||||
void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 );
|
||||
|
||||
/**
|
||||
* \brief SHA-512 process buffer
|
||||
*
|
||||
* \param ctx SHA-512 context
|
||||
* \param input buffer holding the data
|
||||
* \param ilen length of the input data
|
||||
*/
|
||||
void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input,
|
||||
size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief SHA-512 final digest
|
||||
*
|
||||
* \param ctx SHA-512 context
|
||||
* \param output SHA-384/512 checksum result
|
||||
*/
|
||||
void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64] );
|
||||
|
||||
/* Internal use */
|
||||
void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] );
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,27 +1,25 @@
|
||||
/* mbedTLS internal tests wrapped into Unity
|
||||
/* mbedTLS self-tests as unit tests
|
||||
|
||||
Focus on testing functionality where we use ESP32 hardware
|
||||
accelerated crypto features.
|
||||
|
||||
See also test_hwcrypto.c
|
||||
See also test_hwcrypto.c in esp32 component, which tests hardware crypto without mbedTLS.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <esp_system.h>
|
||||
#include "mbedtls/sha1.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/sha512.h"
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/bignum.h"
|
||||
#include "mbedtls/rsa.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
|
||||
static int mbedtls_alt_sha256_self_test( int verbose );
|
||||
|
||||
TEST_CASE("mbedtls SHA self-tests", "[mbedtls]")
|
||||
{
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha1_self_test(1), "SHA1 self-tests should pass.");
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_alt_sha256_self_test(1), "SHA256 self-tests should pass.");
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha512_self_test(1), "SHA512 self-tests should pass.");
|
||||
}
|
||||
#include "sdkconfig.h"
|
||||
|
||||
TEST_CASE("mbedtls AES self-tests", "[aes]")
|
||||
{
|
||||
@ -33,102 +31,8 @@ TEST_CASE("mbedtls MPI self-tests", "[bignum]")
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_mpi_self_test(1), "MPI self-tests should pass.");
|
||||
}
|
||||
|
||||
|
||||
/* Following code is a copy of the mbedtls_sha256 test vectors,
|
||||
with the SHA-224 support removed as we don't currently support this hash.
|
||||
*/
|
||||
|
||||
/*
|
||||
* FIPS-180-2 test vectors
|
||||
*/
|
||||
static const unsigned char sha256_test_buf[3][57] = {
|
||||
{ "abc" },
|
||||
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
|
||||
{ "" }
|
||||
};
|
||||
|
||||
static const int sha256_test_buflen[3] = {
|
||||
3, 56, 1000
|
||||
};
|
||||
|
||||
static const unsigned char sha256_test_sum[6][32] = {
|
||||
/*
|
||||
* SHA-256 test vectors
|
||||
*/
|
||||
{
|
||||
0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
|
||||
0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
|
||||
0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
|
||||
0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD
|
||||
},
|
||||
{
|
||||
0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
|
||||
0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
|
||||
0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
|
||||
0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1
|
||||
},
|
||||
{
|
||||
0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
|
||||
0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
|
||||
0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
|
||||
0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Checkup routine
|
||||
*/
|
||||
static int mbedtls_alt_sha256_self_test( int verbose )
|
||||
TEST_CASE("mbedtls RSA self-tests", "[bignum]")
|
||||
{
|
||||
int j, n, buflen, ret = 0;
|
||||
unsigned char buf[1024];
|
||||
unsigned char sha256sum[32];
|
||||
mbedtls_sha256_context ctx;
|
||||
|
||||
for ( j = 0; j < 3; j++ ) {
|
||||
mbedtls_sha256_init( &ctx );
|
||||
|
||||
if ( verbose != 0 ) {
|
||||
printf( " SHA-%d test #%d: ", 256, j + 1 );
|
||||
}
|
||||
|
||||
mbedtls_sha256_starts( &ctx, 0 );
|
||||
|
||||
if ( j == 2 ) {
|
||||
memset( buf, 'a', buflen = 1000 );
|
||||
|
||||
for ( n = 0; n < 1000; n++ ) {
|
||||
mbedtls_sha256_update( &ctx, buf, buflen );
|
||||
}
|
||||
} else
|
||||
mbedtls_sha256_update( &ctx, sha256_test_buf[j],
|
||||
sha256_test_buflen[j] );
|
||||
|
||||
mbedtls_sha256_finish( &ctx, sha256sum );
|
||||
|
||||
if ( memcmp( sha256sum, sha256_test_sum[j], 32 ) != 0 ) {
|
||||
if ( verbose != 0 ) {
|
||||
printf( "failed\n" );
|
||||
}
|
||||
|
||||
mbedtls_sha256_free( &ctx );
|
||||
|
||||
ret = 1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ( verbose != 0 ) {
|
||||
printf( "passed\n" );
|
||||
}
|
||||
|
||||
mbedtls_sha256_free( &ctx );
|
||||
}
|
||||
|
||||
if ( verbose != 0 ) {
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
return ( ret );
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_rsa_self_test(1), "RSA self-tests should pass.");
|
||||
}
|
||||
|
||||
|
168
components/mbedtls/test/test_mbedtls_mpi.c
Normal file
168
components/mbedtls/test/test_mbedtls_mpi.c
Normal file
@ -0,0 +1,168 @@
|
||||
/* mbedTLS bignum (MPI) self-tests as unit tests
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <esp_system.h>
|
||||
#include "mbedtls/bignum.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
|
||||
/* Debugging function to print an MPI number to stdout. Happens to
|
||||
print output that can be copy-pasted directly into a Python shell.
|
||||
*/
|
||||
void mbedtls_mpi_printf(const char *name, const mbedtls_mpi *X)
|
||||
{
|
||||
static char buf[1024];
|
||||
size_t n;
|
||||
memset(buf, 0, sizeof(buf));
|
||||
mbedtls_mpi_write_string(X, 16, buf, sizeof(buf)-1, &n);
|
||||
if(n) {
|
||||
printf("%s = 0x%s\n", name, buf);
|
||||
} else {
|
||||
printf("%s = TOOLONG\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Assert E = A * B */
|
||||
static void test_bignum_mult(const char *a_str, const char *b_str, const char *e_str, size_t mod_bits)
|
||||
{
|
||||
mbedtls_mpi A, B, X, E, M;
|
||||
char x_buf[1024] = { 0 };
|
||||
size_t x_buf_len = 0;
|
||||
|
||||
mbedtls_mpi_init(&A);
|
||||
mbedtls_mpi_init(&B);
|
||||
mbedtls_mpi_init(&X);
|
||||
mbedtls_mpi_init(&E);
|
||||
|
||||
TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&A, 16, a_str));
|
||||
TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&B, 16, b_str));
|
||||
|
||||
/* E = A * B */
|
||||
TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&E, 16, e_str));
|
||||
TEST_ASSERT_FALSE(mbedtls_mpi_mul_mpi(&X, &A, &B));
|
||||
|
||||
mbedtls_mpi_write_string(&X, 16, x_buf, sizeof(x_buf)-1, &x_buf_len);
|
||||
TEST_ASSERT_EQUAL_STRING_MESSAGE(e_str, x_buf, "mbedtls_mpi_mul_mpi result wrong");
|
||||
|
||||
/* if mod_bits arg is set, also do a esp_mpi_mul_mod() call */
|
||||
if (mod_bits > 0) {
|
||||
mbedtls_mpi_init(&M);
|
||||
for(int i = 0; i < mod_bits; i++) {
|
||||
mbedtls_mpi_set_bit(&M, i, 1);
|
||||
}
|
||||
|
||||
TEST_ASSERT_FALSE(esp_mpi_mul_mpi_mod(&X, &A, &B, &M));
|
||||
|
||||
mbedtls_mpi_write_string(&X, 16, x_buf, sizeof(x_buf)-1, &x_buf_len);
|
||||
TEST_ASSERT_EQUAL_STRING_MESSAGE(e_str, x_buf, "esp_mpi_mul_mpi_mod result wrong");
|
||||
|
||||
mbedtls_mpi_free(&M);
|
||||
}
|
||||
|
||||
|
||||
mbedtls_mpi_free(&A);
|
||||
mbedtls_mpi_free(&B);
|
||||
mbedtls_mpi_free(&X);
|
||||
mbedtls_mpi_free(&E);
|
||||
}
|
||||
|
||||
TEST_CASE("test MPI multiplication", "[bignum]")
|
||||
{
|
||||
/* Run some trivial numbers tests w/ various high modulo bit counts,
|
||||
should make no difference to the result
|
||||
*/
|
||||
for(int i = 512; i <= 4096; i+= 512) {
|
||||
test_bignum_mult("10", "100", "1000",
|
||||
i);
|
||||
}
|
||||
|
||||
test_bignum_mult("60006FA8D3E3BD746BE39B860FFAADB4F108E15CF2ED8F685FB0E86CC4CB107A488720B41C3F1E18550F00619CD3CA8442296ECB54D2F52ECEE5346D310195700000000",
|
||||
"BF474CA7",
|
||||
"047BB102CAF58A48D3D97E4231BC0B753051D8232B9B939A2A4E310F88E65FEFD7762FC2DE0E2BAD6AA51A391DFFABD120653A312E4998F42E2C03AA404EE63B67275BC100000000",
|
||||
1024);
|
||||
|
||||
test_bignum_mult("49493AC229831EC01EEB01EAF3BBEBC44768EADF9ABC30C87D1791F5E04245756ED4965361EC0599626884DF079B6B5738985CE76BD66FAA67E3AAAD60775D5C9D44C09FDF9E27C033696C007BE1C540D718CA148BA01FFA4A358541E9E9F02F72BE37AFAB037DAEA5E3669A770400D2F4A5DBBD83A83919D05E3DD64787BC80000000",
|
||||
"B878CC29",
|
||||
"34CF37013066D5BDA2C86CF1FE7BDA66604E0D55DAFF9864B6E727BFF5871012B0AB73D28D4E100BA1E4607AA2A247C912FDBC435C6BF7C5F8E00278AE1381B1E5F6E3D52D2CBE819F0D65CB37370666D156E7A7B1FD4698D8C9D3165FC8A83F9293C839521993619CCF8180E521300C4306206C9121D629754F1FCC7839BF6DFAF33080000000",
|
||||
3072);
|
||||
|
||||
test_bignum_mult("24BF6185468786FDD303083D25E64EFC66CA472BC44D253102F8B4A9D3BFA75091386C0077937FE33FA3252D28855837AE1B484A8A9A45F7EE8C0C634F9E8CDDF79C5CE07EE72C7F123142198164234CABB724CF78B8173B9F880FC86322407AF1FEDFDDE2BEB674CA15F3E81A1521E071513A1E85B5DFA031F21ECAE9A34D",
|
||||
"010001",
|
||||
"24BF8644A80CCD855A00DB402E2374E2B5C6ADF60B78E97E2829B7A288697B103888FD38E393F776BF8664D04DB280BD0652F665D2E4D0923483FAEF5C01DC7C847A547CDBC7AB663EB0544AC37DA4B0CF03D0869D878FF3B6C3AF5072EAA39D3279D1DCC29C9933808ABDFE0DFD3BF59331AB6FBFD46556119250BD086E36A34D",
|
||||
1536);
|
||||
|
||||
test_bignum_mult("-5D88B669C417EDD02213723546A906B7E9DA7683780E9B54856A2147467ADA316F8819D69486FC8056FE1E8EA7DEC5D5EF12340B95C4FC966F4B348D35893620",
|
||||
"9AE7FBC99546432DF71896FC239EADAEF38D18D2B2F0E2DD275AA977E2BF4411F5A3B2A5D33605AEBBCCBA7FEB9F2D2FA74206CEC169D74BF5A8C50D6F48EA08",
|
||||
"-38990016EB21810E3B5E6AEE339AEE72BB7CD629C4C9270A3D832701A2949BC82B2BE5A7F900C0C9937464699862821976095187D646884E8FBF01DE8C3442F3BC97B670AF573EFB74A9BBEBE4432EE74B0A83BBCDF59485D332B1FF49EB461A3A8B12C38FD72C7772D75EC6EBA5633199540C47678BD2F4ADEEA40830C2F100",
|
||||
2048);
|
||||
|
||||
|
||||
/* 1 << 2050 * 0X1234 */
|
||||
test_bignum_mult("400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"1234",
|
||||
"48D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
3072);
|
||||
|
||||
/* multiply a 1178 bit number by a 2050 bit number */
|
||||
test_bignum_mult("AAAAAAAAAA75124938ABBECD0EEEEE333333333333333333333FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAAABBBBBBBBBBBBBBBBBBBB000000000000000000000000000000000004988A5293848932948872398400000000000FFFFFFFFFFF0000000000000EDFABC0204048975876873487387478327482374871327482347328742837483247283748234723874238",
|
||||
"390587293875124938ABBECD0EEEEE3333333333333333333333333333333399999888000AAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBB00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EDFABC0204048975876873487387478327482374871327482347328742837483247283748234723874238478327400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003012111111111111111100000000000000000000000111111111111111111111111",
|
||||
"02603AF70D0421C1AD82CE623F28F70B128118D06D00C27D433EC25BA86E6105C3890A0B1973B8BE068CA68E159A21078785DDB37F94216FBF4AEC939958AF4B8CEA2A48895CECA87562FC846EAAE0C866AF9D41EEABFB1D579F5828E9666A15E2AF946F16A189B5C645872FDCA247D309AB0BCAFB0D112881186FCFFEDC87061B4AE4A375E9BBCF579A7BC87A8EAC8C6F66E107986FC603F920F5E1A0FD8C619D88D90066FFFC8F4DB77437EBD7E3BD7E398C4C01F93426E347E039DCA7B0A73C0C90A9C4271BB761ADFF88971D190CE5DA98EFC5D7390D33BC034908AF81D784A4D7F32D0902E0C5DABC706635D5A28FC0E3A364EDEB21E8E117041D0E4B51CA6F9684F434057E7FCF2AF6BD050334B1D11E043B0967154E57354B681161D3C618974D5A7E0385755B80B931AE9B59DD4402BAEC206F04B8440741B3C4CA6D9F7DAF0AE6B3BF1B24B76C2F12B9E9A7C50D32E2093608FC9A30CBD852329E64A9AE0BC3F513899EBFA28629C1DF38081FB8C6630408F70D7B9A37701ABA4176C8B7DCB8CC78BD7783B861A7FC50862E75191DB8",
|
||||
4096);
|
||||
}
|
||||
|
||||
static void test_bignum_modexp(const char *z_str, const char *x_str, const char *y_str, const char *m_str)
|
||||
{
|
||||
mbedtls_mpi Z, X, Y, M;
|
||||
char z_buf[400] = { 0 };
|
||||
size_t z_buf_len = 0;
|
||||
|
||||
mbedtls_mpi_init(&Z);
|
||||
mbedtls_mpi_init(&X);
|
||||
mbedtls_mpi_init(&Y);
|
||||
mbedtls_mpi_init(&M);
|
||||
|
||||
TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&X, 16, x_str));
|
||||
TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&Y, 16, y_str));
|
||||
TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&M, 16, m_str));
|
||||
|
||||
//mbedtls_mpi_printf("X", &X);
|
||||
//mbedtls_mpi_printf("X", &Y);
|
||||
//mbedtls_mpi_printf("M", &M);
|
||||
|
||||
/* Z = (X ^ Y) mod M */
|
||||
TEST_ASSERT_FALSE(mbedtls_mpi_exp_mod(&Z, &X, &Y, &M, NULL));
|
||||
|
||||
mbedtls_mpi_write_string(&Z, 16, z_buf, sizeof(z_buf)-1, &z_buf_len);
|
||||
TEST_ASSERT_EQUAL_STRING_MESSAGE(z_str, z_buf, "mbedtls_mpi_exp_mod incorrect");
|
||||
}
|
||||
|
||||
TEST_CASE("test MPI modexp", "[bignum]")
|
||||
{
|
||||
test_bignum_modexp("01000000", "1000", "2", "FFFFFFFF");
|
||||
test_bignum_modexp("014B5A90", "1234", "2", "FFFFFFF");
|
||||
test_bignum_modexp("01234321", "1111", "2", "FFFFFFFF");
|
||||
test_bignum_modexp("02", "5", "1", "3");
|
||||
test_bignum_modexp("22", "55", "1", "33");
|
||||
test_bignum_modexp("0222", "555", "1", "333");
|
||||
test_bignum_modexp("2222", "5555", "1", "3333");
|
||||
test_bignum_modexp("11", "5555", "1", "33");
|
||||
|
||||
test_bignum_modexp("55", "1111", "1", "77");
|
||||
test_bignum_modexp("88", "1111", "2", "BB");
|
||||
|
||||
test_bignum_modexp("01000000", "2", "128",
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
|
||||
|
||||
/* failures below here... */
|
||||
test_bignum_modexp("0ABCDEF12345", "ABCDEF12345", "1", "FFFFFFFFFFFF");
|
||||
test_bignum_modexp("0ABCDE", "ABCDE", "1", "FFFFF");
|
||||
|
||||
test_bignum_modexp("04", "2", "2", "9");
|
||||
}
|
||||
|
250
components/mbedtls/test/test_mbedtls_sha.c
Normal file
250
components/mbedtls/test/test_mbedtls_sha.c
Normal file
@ -0,0 +1,250 @@
|
||||
/* mbedTLS SHA unit tests
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <esp_system.h>
|
||||
#include "mbedtls/sha1.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/sha512.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
TEST_CASE("mbedtls SHA self-tests", "[mbedtls]")
|
||||
{
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha1_self_test(1), "SHA1 self-tests should pass.");
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha256_self_test(1), "SHA256 self-tests should pass.");
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha512_self_test(1), "SHA512 self-tests should pass.");
|
||||
TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha512_self_test(1), "SHA512 self-tests should pass.");
|
||||
}
|
||||
|
||||
static const unsigned char *one_hundred_as = (unsigned char *)
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
|
||||
static const unsigned char *one_hundred_bs = (unsigned char *)
|
||||
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
|
||||
|
||||
static const uint8_t sha256_thousand_as[32] = {
|
||||
0x41, 0xed, 0xec, 0xe4, 0x2d, 0x63, 0xe8, 0xd9, 0xbf, 0x51, 0x5a, 0x9b, 0xa6, 0x93, 0x2e, 0x1c,
|
||||
0x20, 0xcb, 0xc9, 0xf5, 0xa5, 0xd1, 0x34, 0x64, 0x5a, 0xdb, 0x5d, 0xb1, 0xb9, 0x73, 0x7e, 0xa3 };
|
||||
|
||||
static const uint8_t sha256_thousand_bs[32] = {
|
||||
0xf6, 0xf1, 0x18, 0xe1, 0x20, 0xe5, 0x2b, 0xe0, 0xbd, 0x0c, 0xfd, 0xf2, 0x79, 0x4c, 0xd1, 0x2c, 0x07, 0x68, 0x6c, 0xc8, 0x71, 0x23, 0x5a, 0xc2, 0xf1, 0x14, 0x59, 0x37, 0x8e, 0x6d, 0x23, 0x5b
|
||||
};
|
||||
|
||||
static const uint8_t sha512_thousand_bs[64] = {
|
||||
0xa6, 0x68, 0x68, 0xa3, 0x73, 0x53, 0x2a, 0x5c, 0xc3, 0x3f, 0xbf, 0x43, 0x4e, 0xba, 0x10, 0x86, 0xb3, 0x87, 0x09, 0xe9, 0x14, 0x3f, 0xbf, 0x37, 0x67, 0x8d, 0x43, 0xd9, 0x9b, 0x95, 0x08, 0xd5, 0x80, 0x2d, 0xbe, 0x9d, 0xe9, 0x1a, 0x54, 0xab, 0x9e, 0xbc, 0x8a, 0x08, 0xa0, 0x1a, 0x89, 0xd8, 0x72, 0x68, 0xdf, 0x52, 0x69, 0x7f, 0x1c, 0x70, 0xda, 0xe8, 0x3f, 0xe5, 0xae, 0x5a, 0xfc, 0x9d
|
||||
};
|
||||
|
||||
static const uint8_t sha384_thousand_bs[48] = {
|
||||
0x6d, 0xe5, 0xf5, 0x88, 0x57, 0x60, 0x83, 0xff, 0x7c, 0x94, 0x61, 0x5f, 0x8d, 0x96, 0xf2, 0x76, 0xd5, 0x3f, 0x77, 0x0c, 0x8e, 0xc1, 0xbf, 0xb6, 0x04, 0x27, 0xa4, 0xba, 0xea, 0x6c, 0x68, 0x44, 0xbd, 0xb0, 0x9c, 0xef, 0x6a, 0x09, 0x28, 0xe8, 0x1f, 0xfc, 0x95, 0x03, 0x69, 0x99, 0xab, 0x1a
|
||||
};
|
||||
|
||||
static const uint8_t sha1_thousand_as[20] = {
|
||||
0x29, 0x1e, 0x9a, 0x6c, 0x66, 0x99, 0x49, 0x49, 0xb5, 0x7b, 0xa5,
|
||||
0xe6, 0x50, 0x36, 0x1e, 0x98, 0xfc, 0x36, 0xb1, 0xba };
|
||||
|
||||
TEST_CASE("mbedtls SHA interleaving", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha1_context sha1_ctx;
|
||||
mbedtls_sha256_context sha256_ctx;
|
||||
mbedtls_sha512_context sha512_ctx;
|
||||
unsigned char sha1[20], sha256[32], sha512[64];
|
||||
|
||||
mbedtls_sha1_init(&sha1_ctx);
|
||||
mbedtls_sha256_init(&sha256_ctx);
|
||||
mbedtls_sha512_init(&sha512_ctx);
|
||||
|
||||
mbedtls_sha1_starts(&sha1_ctx);
|
||||
mbedtls_sha256_starts(&sha256_ctx, false);
|
||||
mbedtls_sha512_starts(&sha512_ctx, false);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
mbedtls_sha1_update(&sha1_ctx, one_hundred_as, 100);
|
||||
mbedtls_sha256_update(&sha256_ctx, one_hundred_as, 100);
|
||||
mbedtls_sha512_update(&sha512_ctx, one_hundred_bs, 100);
|
||||
}
|
||||
|
||||
mbedtls_sha1_finish(&sha1_ctx, sha1);
|
||||
mbedtls_sha256_finish(&sha256_ctx, sha256);
|
||||
mbedtls_sha512_finish(&sha512_ctx, sha512);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 calculation");
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 calculation");
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_thousand_as, sha1, 20, "SHA1 calculation");
|
||||
}
|
||||
|
||||
static xSemaphoreHandle done_sem;
|
||||
static void tskRunSHA1Test(void *pvParameters)
|
||||
{
|
||||
mbedtls_sha1_context sha1_ctx;
|
||||
unsigned char sha1[20];
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
mbedtls_sha1_init(&sha1_ctx);
|
||||
mbedtls_sha1_starts(&sha1_ctx);
|
||||
for (int j = 0; j < 10; j++) {
|
||||
mbedtls_sha1_update(&sha1_ctx, (unsigned char *)one_hundred_as, 100);
|
||||
}
|
||||
mbedtls_sha1_finish(&sha1_ctx, sha1);
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_thousand_as, sha1, 20, "SHA1 calculation");
|
||||
}
|
||||
xSemaphoreGive(done_sem);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void tskRunSHA256Test(void *pvParameters)
|
||||
{
|
||||
mbedtls_sha256_context sha256_ctx;
|
||||
unsigned char sha256[32];
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
mbedtls_sha256_init(&sha256_ctx);
|
||||
mbedtls_sha256_starts(&sha256_ctx, false);
|
||||
for (int j = 0; j < 10; j++) {
|
||||
mbedtls_sha256_update(&sha256_ctx, (unsigned char *)one_hundred_bs, 100);
|
||||
}
|
||||
mbedtls_sha256_finish(&sha256_ctx, sha256);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_bs, sha256, 32, "SHA256 calculation");
|
||||
}
|
||||
xSemaphoreGive(done_sem);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls SHA multithreading", "[mbedtls]")
|
||||
{
|
||||
done_sem = xSemaphoreCreateCounting(4, 0);
|
||||
xTaskCreate(tskRunSHA1Test, "SHA1Task1", 8192, NULL, 3, NULL);
|
||||
xTaskCreate(tskRunSHA1Test, "SHA1Task2", 8192, NULL, 3, NULL);
|
||||
xTaskCreate(tskRunSHA256Test, "SHA256Task1", 8192, NULL, 3, NULL);
|
||||
xTaskCreate(tskRunSHA256Test, "SHA256Task2", 8192, NULL, 3, NULL);
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(!xSemaphoreTake(done_sem, 10000/portTICK_PERIOD_MS)) {
|
||||
TEST_FAIL_MESSAGE("done_sem not released by test task");
|
||||
}
|
||||
}
|
||||
vSemaphoreDelete(done_sem);
|
||||
}
|
||||
|
||||
void tskRunSHASelftests(void *param)
|
||||
{
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if(mbedtls_sha1_self_test(1)) {
|
||||
printf("SHA1 self-tests failed.\n");
|
||||
while(1) {}
|
||||
}
|
||||
|
||||
if(mbedtls_sha256_self_test(1)) {
|
||||
printf("SHA256 self-tests failed.\n");
|
||||
while(1) {}
|
||||
}
|
||||
|
||||
if(mbedtls_sha512_self_test(1)) {
|
||||
printf("SHA512 self-tests failed.\n");
|
||||
while(1) {}
|
||||
}
|
||||
|
||||
if(mbedtls_sha512_self_test(1)) {
|
||||
printf("SHA512 self-tests failed.\n");
|
||||
while(1) {}
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(done_sem);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls SHA self-tests multithreaded", "[mbedtls]")
|
||||
{
|
||||
done_sem = xSemaphoreCreateCounting(2, 0);
|
||||
xTaskCreate(tskRunSHASelftests, "SHASelftests1", 8192, NULL, 3, NULL);
|
||||
xTaskCreate(tskRunSHASelftests, "SHASelftests2", 8192, NULL, 3, NULL);
|
||||
|
||||
for(int i = 0; i < 2; i++) {
|
||||
if(!xSemaphoreTake(done_sem, 10000/portTICK_PERIOD_MS)) {
|
||||
TEST_FAIL_MESSAGE("done_sem not released by test task");
|
||||
}
|
||||
}
|
||||
vSemaphoreDelete(done_sem);
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls SHA512 clone", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha512_context ctx;
|
||||
mbedtls_sha512_context clone;
|
||||
unsigned char sha512[64];
|
||||
|
||||
mbedtls_sha512_init(&ctx);
|
||||
mbedtls_sha512_starts(&ctx, false);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
mbedtls_sha512_update(&ctx, one_hundred_bs, 100);
|
||||
}
|
||||
|
||||
mbedtls_sha512_clone(&clone, &ctx);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
mbedtls_sha512_update(&ctx, one_hundred_bs, 100);
|
||||
mbedtls_sha512_update(&clone, one_hundred_bs, 100);
|
||||
}
|
||||
mbedtls_sha512_finish(&ctx, sha512);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 original calculation");
|
||||
|
||||
mbedtls_sha512_finish(&clone, sha512);
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha512_thousand_bs, sha512, 64, "SHA512 cloned calculation");
|
||||
}
|
||||
|
||||
TEST_CASE("mbedtls SHA384 clone", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha512_context ctx;
|
||||
mbedtls_sha512_context clone;
|
||||
unsigned char sha384[48];
|
||||
|
||||
mbedtls_sha512_init(&ctx);
|
||||
mbedtls_sha512_starts(&ctx, true);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
mbedtls_sha512_update(&ctx, one_hundred_bs, 100);
|
||||
}
|
||||
|
||||
mbedtls_sha512_clone(&clone, &ctx);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
mbedtls_sha512_update(&ctx, one_hundred_bs, 100);
|
||||
mbedtls_sha512_update(&clone, one_hundred_bs, 100);
|
||||
}
|
||||
mbedtls_sha512_finish(&ctx, sha384);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha384_thousand_bs, sha384, 48, "SHA512 original calculation");
|
||||
|
||||
mbedtls_sha512_finish(&clone, sha384);
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha384_thousand_bs, sha384, 48, "SHA512 cloned calculation");
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("mbedtls SHA256 clone", "[mbedtls]")
|
||||
{
|
||||
mbedtls_sha256_context ctx;
|
||||
mbedtls_sha256_context clone;
|
||||
unsigned char sha256[64];
|
||||
|
||||
mbedtls_sha256_init(&ctx);
|
||||
mbedtls_sha256_starts(&ctx, false);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
mbedtls_sha256_update(&ctx, one_hundred_as, 100);
|
||||
}
|
||||
|
||||
mbedtls_sha256_clone(&clone, &ctx);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
mbedtls_sha256_update(&ctx, one_hundred_as, 100);
|
||||
mbedtls_sha256_update(&clone, one_hundred_as, 100);
|
||||
}
|
||||
mbedtls_sha256_finish(&ctx, sha256);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 original calculation");
|
||||
|
||||
mbedtls_sha256_finish(&clone, sha256);
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_thousand_as, sha256, 32, "SHA256 cloned calculation");
|
||||
}
|
@ -184,3 +184,29 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz)
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t system_get_time(void)
|
||||
{
|
||||
#if defined( WITH_FRC1 ) || defined( WITH_RTC )
|
||||
return get_time_since_boot();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t system_get_current_time(void) __attribute__((alias("system_get_time")));
|
||||
|
||||
uint32_t system_relative_time(uint32_t current_time)
|
||||
{
|
||||
return system_get_time() - current_time;
|
||||
}
|
||||
|
||||
uint64_t system_get_rtc_time(void)
|
||||
{
|
||||
#ifdef WITH_RTC
|
||||
return get_rtc_time_us();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ static int ssl_pm_reload_crt(SSL *ssl)
|
||||
* Perform the mbedtls SSL handshake instead of mbedtls_ssl_handshake.
|
||||
* We can add debug here.
|
||||
*/
|
||||
LOCAL int mbedtls_handshake( mbedtls_ssl_context *ssl )
|
||||
static int mbedtls_handshake( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -31,6 +31,9 @@
|
||||
#include "esp_log.h"
|
||||
#include "cache_utils.h"
|
||||
|
||||
/* bytes erased by SPIEraseBlock() ROM function */
|
||||
#define BLOCK_ERASE_SIZE 32768
|
||||
|
||||
#if CONFIG_SPI_FLASH_ENABLE_COUNTERS
|
||||
static const char* TAG = "spi_flash";
|
||||
static spi_flash_counters_t s_flash_stats;
|
||||
@ -100,7 +103,7 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size)
|
||||
}
|
||||
size_t start = start_addr / SPI_FLASH_SEC_SIZE;
|
||||
size_t end = start + size / SPI_FLASH_SEC_SIZE;
|
||||
const size_t sectors_per_block = 16;
|
||||
const size_t sectors_per_block = BLOCK_ERASE_SIZE / SPI_FLASH_SEC_SIZE;
|
||||
COUNTER_START();
|
||||
spi_flash_disable_interrupts_caches_and_other_cpu();
|
||||
SpiFlashOpResult rc;
|
||||
@ -129,34 +132,90 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t dest_addr, const void *src, size_t si
|
||||
// Destination alignment is also checked in ROM code, but we can give
|
||||
// better error code here
|
||||
// TODO: add handling of unaligned destinations
|
||||
if (dest_addr % 4 != 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (size % 4 != 0) {
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
if ((uint32_t) src < 0x3ff00000) {
|
||||
// if source address is in DROM, we won't be able to read it
|
||||
// from within SPIWrite
|
||||
// TODO: consider buffering source data using heap and writing it anyway?
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
uint8_t *temp_write_buf = NULL;
|
||||
uint8_t pad_head = 0;
|
||||
uint8_t pad_end = 0;
|
||||
SpiFlashOpResult rc;
|
||||
// Out of bound writes are checked in ROM code, but we can give better
|
||||
// error code here
|
||||
if (dest_addr + size > g_rom_flashchip.chip_size) {
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
COUNTER_START();
|
||||
spi_flash_disable_interrupts_caches_and_other_cpu();
|
||||
SpiFlashOpResult rc;
|
||||
rc = spi_flash_unlock();
|
||||
if (rc == SPI_FLASH_RESULT_OK) {
|
||||
rc = SPIWrite((uint32_t) dest_addr, (const uint32_t*) src, (int32_t) size);
|
||||
COUNTER_ADD_BYTES(write, size);
|
||||
|
||||
while(size >= 1024) {
|
||||
// max need pad byte num for 1024 is 4
|
||||
temp_write_buf = (uint8_t*)malloc(1024 + 4);
|
||||
if(temp_write_buf == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
if(dest_addr%4 != 0) {
|
||||
pad_head = dest_addr%4;
|
||||
pad_end = 4 - pad_head;
|
||||
}
|
||||
memset(temp_write_buf,0xFF,pad_head);
|
||||
memcpy(temp_write_buf + pad_head ,src,1024);
|
||||
memset(temp_write_buf + pad_head + 1024, 0xFF,pad_end);
|
||||
COUNTER_START();
|
||||
spi_flash_disable_interrupts_caches_and_other_cpu();
|
||||
rc = spi_flash_unlock();
|
||||
if (rc == SPI_FLASH_RESULT_OK) {
|
||||
rc = SPIWrite((uint32_t) (dest_addr - pad_head), (const uint32_t*) temp_write_buf, (int32_t) (1024 + pad_head + pad_end));
|
||||
COUNTER_ADD_BYTES(write, 1024 + pad_head + pad_end);
|
||||
}
|
||||
COUNTER_STOP(write);
|
||||
spi_flash_enable_interrupts_caches_and_other_cpu();
|
||||
if(rc != ESP_OK) {
|
||||
free(temp_write_buf);
|
||||
temp_write_buf = NULL;
|
||||
return spi_flash_translate_rc(rc);
|
||||
}
|
||||
|
||||
free(temp_write_buf);
|
||||
temp_write_buf = NULL;
|
||||
size -= 1024;
|
||||
dest_addr += 1024;
|
||||
src = (uint8_t*)src + 1024;
|
||||
}
|
||||
spi_flash_enable_interrupts_caches_and_other_cpu();
|
||||
COUNTER_STOP(write);
|
||||
return spi_flash_translate_rc(rc);
|
||||
if(size > 0) {
|
||||
// max need pad byte num for rand size is 6
|
||||
temp_write_buf = (uint8_t*)malloc(size + 6);
|
||||
if(temp_write_buf == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
if(dest_addr%4 != 0) {
|
||||
pad_head = dest_addr%4;
|
||||
}
|
||||
if ((pad_head + size)%4 != 0){
|
||||
pad_end = 4 - (pad_head + size) % 4;
|
||||
}
|
||||
memset(temp_write_buf,0xFF,pad_head);
|
||||
memcpy(temp_write_buf + pad_head, src, size);
|
||||
memset(temp_write_buf + pad_head + size, 0xFF,pad_end);
|
||||
COUNTER_START();
|
||||
spi_flash_disable_interrupts_caches_and_other_cpu();
|
||||
rc = spi_flash_unlock();
|
||||
if (rc == SPI_FLASH_RESULT_OK) {
|
||||
rc = SPIWrite((uint32_t) (dest_addr - pad_head), (const uint32_t*) temp_write_buf, (int32_t) (size + pad_head + pad_end));
|
||||
COUNTER_ADD_BYTES(write, size + pad_head + pad_end);
|
||||
}
|
||||
COUNTER_STOP(write);
|
||||
spi_flash_enable_interrupts_caches_and_other_cpu();
|
||||
if(rc != ESP_OK) {
|
||||
free(temp_write_buf);
|
||||
temp_write_buf = NULL;
|
||||
return spi_flash_translate_rc(rc);
|
||||
}
|
||||
|
||||
free(temp_write_buf);
|
||||
temp_write_buf = NULL;
|
||||
size = 0;
|
||||
dest_addr += size;
|
||||
src = (uint8_t*)src + size;
|
||||
return spi_flash_translate_rc(rc);
|
||||
}
|
||||
return spi_flash_translate_rc(SPI_FLASH_RESULT_OK);
|
||||
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_read(size_t src_addr, void *dest, size_t size)
|
||||
|
@ -208,6 +208,10 @@ esp_err_t esp_partition_write(const esp_partition_t* partition,
|
||||
size_t dst_offset, const void* src, size_t size)
|
||||
{
|
||||
assert(partition != NULL);
|
||||
//todo : need add ecrypt write support ,size must be 32-bytes align
|
||||
if(partition->encrypted == true) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (dst_offset > partition->size) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
COMPONENT_ADD_INCLUDEDIRS := include port/include
|
||||
COMPONENT_SRCDIRS := src/crypto
|
||||
COMPONENT_SRCDIRS := src/crypto port
|
||||
|
||||
CFLAGS += -DEMBEDDED_SUPP -D__ets__ -Wno-strict-aliasing
|
||||
|
60
components/wpa_supplicant/include/crypto/ms_funcs.h
Normal file
60
components/wpa_supplicant/include/crypto/ms_funcs.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* WPA Supplicant / shared MSCHAPV2 helper functions
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MS_FUNCS_H
|
||||
#define MS_FUNCS_H
|
||||
|
||||
int generate_nt_response(const u8 *auth_challenge, const u8 *peer_challenge,
|
||||
const u8 *username, size_t username_len,
|
||||
const u8 *password, size_t password_len,
|
||||
u8 *response);
|
||||
|
||||
int generate_nt_response_pwhash(const u8 *auth_challenge,
|
||||
const u8 *peer_challenge,
|
||||
const u8 *username, size_t username_len,
|
||||
const u8 *password_hash,
|
||||
u8 *response);
|
||||
int generate_authenticator_response(const u8 *password, size_t password_len,
|
||||
const u8 *peer_challenge,
|
||||
const u8 *auth_challenge,
|
||||
const u8 *username, size_t username_len,
|
||||
const u8 *nt_response, u8 *response);
|
||||
int generate_authenticator_response_pwhash(
|
||||
const u8 *password_hash,
|
||||
const u8 *peer_challenge, const u8 *auth_challenge,
|
||||
const u8 *username, size_t username_len,
|
||||
const u8 *nt_response, u8 *response);
|
||||
int nt_challenge_response(const u8 *challenge, const u8 *password,
|
||||
size_t password_len, u8 *response);
|
||||
|
||||
void challenge_response(const u8 *challenge, const u8 *password_hash,
|
||||
u8 *response);
|
||||
int nt_password_hash(const u8 *password, size_t password_len,
|
||||
u8 *password_hash);
|
||||
int hash_nt_password_hash(const u8 *password_hash, u8 *password_hash_hash);
|
||||
int get_master_key(const u8 *password_hash_hash, const u8 *nt_response,
|
||||
u8 *master_key);
|
||||
int get_asymetric_start_key(const u8 *master_key, u8 *session_key,
|
||||
size_t session_key_len, int is_send,
|
||||
int is_server);
|
||||
int encrypt_pw_block_with_password_hash(
|
||||
const u8 *password, size_t password_len,
|
||||
const u8 *password_hash, u8 *pw_block);
|
||||
int __must_check encry_pw_block_with_password_hash(
|
||||
const u8 *password, size_t password_len,
|
||||
const u8 *password_hash, u8 *pw_block);
|
||||
int __must_check new_password_encrypted_with_old_nt_password_hash(
|
||||
const u8 *new_password, size_t new_password_len,
|
||||
const u8 *old_password, size_t old_password_len,
|
||||
u8 *encrypted_pw_block);
|
||||
void nt_password_hash_encrypted_with_block(const u8 *password_hash,
|
||||
const u8 *block, u8 *cypher);
|
||||
int old_nt_password_hash_encrypted_with_new_nt_password_hash(
|
||||
const u8 *new_password, size_t new_password_len,
|
||||
const u8 *old_password, size_t old_password_len,
|
||||
u8 *encrypted_password_hash);
|
||||
|
||||
#endif /* MS_FUNCS_H */
|
@ -19,6 +19,19 @@
|
||||
#endif /* ets */
|
||||
#include "os.h"
|
||||
|
||||
/* Define platform specific variable type macros */
|
||||
#if defined(ESP_PLATFORM)
|
||||
#include <stdint.h>
|
||||
typedef uint64_t u64;
|
||||
typedef uint32_t u32;
|
||||
typedef uint16_t u16;
|
||||
typedef uint8_t u8;
|
||||
typedef int64_t s64;
|
||||
typedef int32_t s32;
|
||||
typedef int16_t s16;
|
||||
typedef int8_t s8;
|
||||
#endif /*ESP_PLATFORM*/
|
||||
|
||||
#if defined(__XTENSA__)
|
||||
#include <machine/endian.h>
|
||||
#define __BYTE_ORDER BYTE_ORDER
|
||||
|
@ -119,6 +119,7 @@ typedef __uint64_t uint64_t;
|
||||
#endif /* _BYTE_ORDER == _LITTLE_ENDIAN */
|
||||
|
||||
/* Alignment-agnostic encode/decode bytestream to/from little/big endian. */
|
||||
#define INLINE __inline__
|
||||
|
||||
static INLINE uint16_t
|
||||
be16dec(const void *pp)
|
||||
|
64
components/wpa_supplicant/port/os_xtensa.c
Normal file
64
components/wpa_supplicant/port/os_xtensa.c
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* wpa_supplicant/hostapd / Internal implementation of OS specific functions
|
||||
* Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of BSD
|
||||
* license.
|
||||
*
|
||||
* See README and COPYING for more details.
|
||||
*
|
||||
* This file is an example of operating system specific wrapper functions.
|
||||
* This version implements many of the functions internally, so it can be used
|
||||
* to fill in missing functions from the target system C libraries.
|
||||
*
|
||||
* Some of the functions are using standard C library calls in order to keep
|
||||
* this file in working condition to allow the functions to be tested on a
|
||||
* Linux target. Please note that OS_NO_C_LIB_DEFINES needs to be defined for
|
||||
* this file to work correctly. Note that these implementations are only
|
||||
* examples and are not optimized for speed.
|
||||
*/
|
||||
|
||||
#include "crypto/common.h"
|
||||
#include "os.h"
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include "esp_system.h"
|
||||
|
||||
int os_get_time(struct os_time *t)
|
||||
{
|
||||
return gettimeofday((struct timeval*) t, NULL);
|
||||
}
|
||||
|
||||
unsigned long os_random(void)
|
||||
{
|
||||
return esp_random();
|
||||
}
|
||||
|
||||
unsigned long r_rand(void) __attribute__((alias("os_random")));
|
||||
|
||||
|
||||
int os_get_random(unsigned char *buf, size_t len)
|
||||
{
|
||||
int i, j;
|
||||
unsigned long tmp;
|
||||
|
||||
for (i = 0; i < ((len + 3) & ~3) / 4; i++) {
|
||||
tmp = r_rand();
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
if ((i * 4 + j) < len) {
|
||||
buf[i * 4 + j] = (uint8_t)(tmp >> (j * 8));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
494
components/wpa_supplicant/src/crypto/des-internal.c
Normal file
494
components/wpa_supplicant/src/crypto/des-internal.c
Normal file
@ -0,0 +1,494 @@
|
||||
/*
|
||||
* DES and 3DES-EDE ciphers
|
||||
*
|
||||
* Modifications to LibTomCrypt implementation:
|
||||
* Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include "wpa/includes.h"
|
||||
|
||||
#include "wpa/common.h"
|
||||
#include "crypto/crypto.h"
|
||||
//#include "des_i.h"
|
||||
|
||||
/*
|
||||
* This implementation is based on a DES implementation included in
|
||||
* LibTomCrypt. The version here is modified to fit in wpa_supplicant/hostapd
|
||||
* coding style.
|
||||
*/
|
||||
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
|
||||
*/
|
||||
|
||||
/**
|
||||
DES code submitted by Dobes Vandermeer
|
||||
*/
|
||||
|
||||
#define ROLc(x, y) \
|
||||
((((unsigned long) (x) << (unsigned long) ((y) & 31)) | \
|
||||
(((unsigned long) (x) & 0xFFFFFFFFUL) >> \
|
||||
(unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
|
||||
#define RORc(x, y) \
|
||||
(((((unsigned long) (x) & 0xFFFFFFFFUL) >> \
|
||||
(unsigned long) ((y) & 31)) | \
|
||||
((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & \
|
||||
0xFFFFFFFFUL)
|
||||
|
||||
|
||||
static const u32 bytebit[8] =
|
||||
{
|
||||
0200, 0100, 040, 020, 010, 04, 02, 01
|
||||
};
|
||||
|
||||
static const u32 bigbyte[24] =
|
||||
{
|
||||
0x800000UL, 0x400000UL, 0x200000UL, 0x100000UL,
|
||||
0x80000UL, 0x40000UL, 0x20000UL, 0x10000UL,
|
||||
0x8000UL, 0x4000UL, 0x2000UL, 0x1000UL,
|
||||
0x800UL, 0x400UL, 0x200UL, 0x100UL,
|
||||
0x80UL, 0x40UL, 0x20UL, 0x10UL,
|
||||
0x8UL, 0x4UL, 0x2UL, 0x1L
|
||||
};
|
||||
|
||||
/* Use the key schedule specific in the standard (ANSI X3.92-1981) */
|
||||
|
||||
static const u8 pc1[56] = {
|
||||
56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
|
||||
9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
|
||||
62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
|
||||
13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
|
||||
};
|
||||
|
||||
static const u8 totrot[16] = {
|
||||
1, 2, 4, 6,
|
||||
8, 10, 12, 14,
|
||||
15, 17, 19, 21,
|
||||
23, 25, 27, 28
|
||||
};
|
||||
|
||||
static const u8 pc2[48] = {
|
||||
13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
|
||||
22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
|
||||
40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
|
||||
43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
|
||||
};
|
||||
|
||||
|
||||
static const u32 SP1[64] =
|
||||
{
|
||||
0x01010400UL, 0x00000000UL, 0x00010000UL, 0x01010404UL,
|
||||
0x01010004UL, 0x00010404UL, 0x00000004UL, 0x00010000UL,
|
||||
0x00000400UL, 0x01010400UL, 0x01010404UL, 0x00000400UL,
|
||||
0x01000404UL, 0x01010004UL, 0x01000000UL, 0x00000004UL,
|
||||
0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00010400UL,
|
||||
0x00010400UL, 0x01010000UL, 0x01010000UL, 0x01000404UL,
|
||||
0x00010004UL, 0x01000004UL, 0x01000004UL, 0x00010004UL,
|
||||
0x00000000UL, 0x00000404UL, 0x00010404UL, 0x01000000UL,
|
||||
0x00010000UL, 0x01010404UL, 0x00000004UL, 0x01010000UL,
|
||||
0x01010400UL, 0x01000000UL, 0x01000000UL, 0x00000400UL,
|
||||
0x01010004UL, 0x00010000UL, 0x00010400UL, 0x01000004UL,
|
||||
0x00000400UL, 0x00000004UL, 0x01000404UL, 0x00010404UL,
|
||||
0x01010404UL, 0x00010004UL, 0x01010000UL, 0x01000404UL,
|
||||
0x01000004UL, 0x00000404UL, 0x00010404UL, 0x01010400UL,
|
||||
0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00000000UL,
|
||||
0x00010004UL, 0x00010400UL, 0x00000000UL, 0x01010004UL
|
||||
};
|
||||
|
||||
static const u32 SP2[64] =
|
||||
{
|
||||
0x80108020UL, 0x80008000UL, 0x00008000UL, 0x00108020UL,
|
||||
0x00100000UL, 0x00000020UL, 0x80100020UL, 0x80008020UL,
|
||||
0x80000020UL, 0x80108020UL, 0x80108000UL, 0x80000000UL,
|
||||
0x80008000UL, 0x00100000UL, 0x00000020UL, 0x80100020UL,
|
||||
0x00108000UL, 0x00100020UL, 0x80008020UL, 0x00000000UL,
|
||||
0x80000000UL, 0x00008000UL, 0x00108020UL, 0x80100000UL,
|
||||
0x00100020UL, 0x80000020UL, 0x00000000UL, 0x00108000UL,
|
||||
0x00008020UL, 0x80108000UL, 0x80100000UL, 0x00008020UL,
|
||||
0x00000000UL, 0x00108020UL, 0x80100020UL, 0x00100000UL,
|
||||
0x80008020UL, 0x80100000UL, 0x80108000UL, 0x00008000UL,
|
||||
0x80100000UL, 0x80008000UL, 0x00000020UL, 0x80108020UL,
|
||||
0x00108020UL, 0x00000020UL, 0x00008000UL, 0x80000000UL,
|
||||
0x00008020UL, 0x80108000UL, 0x00100000UL, 0x80000020UL,
|
||||
0x00100020UL, 0x80008020UL, 0x80000020UL, 0x00100020UL,
|
||||
0x00108000UL, 0x00000000UL, 0x80008000UL, 0x00008020UL,
|
||||
0x80000000UL, 0x80100020UL, 0x80108020UL, 0x00108000UL
|
||||
};
|
||||
|
||||
static const u32 SP3[64] =
|
||||
{
|
||||
0x00000208UL, 0x08020200UL, 0x00000000UL, 0x08020008UL,
|
||||
0x08000200UL, 0x00000000UL, 0x00020208UL, 0x08000200UL,
|
||||
0x00020008UL, 0x08000008UL, 0x08000008UL, 0x00020000UL,
|
||||
0x08020208UL, 0x00020008UL, 0x08020000UL, 0x00000208UL,
|
||||
0x08000000UL, 0x00000008UL, 0x08020200UL, 0x00000200UL,
|
||||
0x00020200UL, 0x08020000UL, 0x08020008UL, 0x00020208UL,
|
||||
0x08000208UL, 0x00020200UL, 0x00020000UL, 0x08000208UL,
|
||||
0x00000008UL, 0x08020208UL, 0x00000200UL, 0x08000000UL,
|
||||
0x08020200UL, 0x08000000UL, 0x00020008UL, 0x00000208UL,
|
||||
0x00020000UL, 0x08020200UL, 0x08000200UL, 0x00000000UL,
|
||||
0x00000200UL, 0x00020008UL, 0x08020208UL, 0x08000200UL,
|
||||
0x08000008UL, 0x00000200UL, 0x00000000UL, 0x08020008UL,
|
||||
0x08000208UL, 0x00020000UL, 0x08000000UL, 0x08020208UL,
|
||||
0x00000008UL, 0x00020208UL, 0x00020200UL, 0x08000008UL,
|
||||
0x08020000UL, 0x08000208UL, 0x00000208UL, 0x08020000UL,
|
||||
0x00020208UL, 0x00000008UL, 0x08020008UL, 0x00020200UL
|
||||
};
|
||||
|
||||
static const u32 SP4[64] =
|
||||
{
|
||||
0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL,
|
||||
0x00802080UL, 0x00800081UL, 0x00800001UL, 0x00002001UL,
|
||||
0x00000000UL, 0x00802000UL, 0x00802000UL, 0x00802081UL,
|
||||
0x00000081UL, 0x00000000UL, 0x00800080UL, 0x00800001UL,
|
||||
0x00000001UL, 0x00002000UL, 0x00800000UL, 0x00802001UL,
|
||||
0x00000080UL, 0x00800000UL, 0x00002001UL, 0x00002080UL,
|
||||
0x00800081UL, 0x00000001UL, 0x00002080UL, 0x00800080UL,
|
||||
0x00002000UL, 0x00802080UL, 0x00802081UL, 0x00000081UL,
|
||||
0x00800080UL, 0x00800001UL, 0x00802000UL, 0x00802081UL,
|
||||
0x00000081UL, 0x00000000UL, 0x00000000UL, 0x00802000UL,
|
||||
0x00002080UL, 0x00800080UL, 0x00800081UL, 0x00000001UL,
|
||||
0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL,
|
||||
0x00802081UL, 0x00000081UL, 0x00000001UL, 0x00002000UL,
|
||||
0x00800001UL, 0x00002001UL, 0x00802080UL, 0x00800081UL,
|
||||
0x00002001UL, 0x00002080UL, 0x00800000UL, 0x00802001UL,
|
||||
0x00000080UL, 0x00800000UL, 0x00002000UL, 0x00802080UL
|
||||
};
|
||||
|
||||
static const u32 SP5[64] =
|
||||
{
|
||||
0x00000100UL, 0x02080100UL, 0x02080000UL, 0x42000100UL,
|
||||
0x00080000UL, 0x00000100UL, 0x40000000UL, 0x02080000UL,
|
||||
0x40080100UL, 0x00080000UL, 0x02000100UL, 0x40080100UL,
|
||||
0x42000100UL, 0x42080000UL, 0x00080100UL, 0x40000000UL,
|
||||
0x02000000UL, 0x40080000UL, 0x40080000UL, 0x00000000UL,
|
||||
0x40000100UL, 0x42080100UL, 0x42080100UL, 0x02000100UL,
|
||||
0x42080000UL, 0x40000100UL, 0x00000000UL, 0x42000000UL,
|
||||
0x02080100UL, 0x02000000UL, 0x42000000UL, 0x00080100UL,
|
||||
0x00080000UL, 0x42000100UL, 0x00000100UL, 0x02000000UL,
|
||||
0x40000000UL, 0x02080000UL, 0x42000100UL, 0x40080100UL,
|
||||
0x02000100UL, 0x40000000UL, 0x42080000UL, 0x02080100UL,
|
||||
0x40080100UL, 0x00000100UL, 0x02000000UL, 0x42080000UL,
|
||||
0x42080100UL, 0x00080100UL, 0x42000000UL, 0x42080100UL,
|
||||
0x02080000UL, 0x00000000UL, 0x40080000UL, 0x42000000UL,
|
||||
0x00080100UL, 0x02000100UL, 0x40000100UL, 0x00080000UL,
|
||||
0x00000000UL, 0x40080000UL, 0x02080100UL, 0x40000100UL
|
||||
};
|
||||
|
||||
static const u32 SP6[64] =
|
||||
{
|
||||
0x20000010UL, 0x20400000UL, 0x00004000UL, 0x20404010UL,
|
||||
0x20400000UL, 0x00000010UL, 0x20404010UL, 0x00400000UL,
|
||||
0x20004000UL, 0x00404010UL, 0x00400000UL, 0x20000010UL,
|
||||
0x00400010UL, 0x20004000UL, 0x20000000UL, 0x00004010UL,
|
||||
0x00000000UL, 0x00400010UL, 0x20004010UL, 0x00004000UL,
|
||||
0x00404000UL, 0x20004010UL, 0x00000010UL, 0x20400010UL,
|
||||
0x20400010UL, 0x00000000UL, 0x00404010UL, 0x20404000UL,
|
||||
0x00004010UL, 0x00404000UL, 0x20404000UL, 0x20000000UL,
|
||||
0x20004000UL, 0x00000010UL, 0x20400010UL, 0x00404000UL,
|
||||
0x20404010UL, 0x00400000UL, 0x00004010UL, 0x20000010UL,
|
||||
0x00400000UL, 0x20004000UL, 0x20000000UL, 0x00004010UL,
|
||||
0x20000010UL, 0x20404010UL, 0x00404000UL, 0x20400000UL,
|
||||
0x00404010UL, 0x20404000UL, 0x00000000UL, 0x20400010UL,
|
||||
0x00000010UL, 0x00004000UL, 0x20400000UL, 0x00404010UL,
|
||||
0x00004000UL, 0x00400010UL, 0x20004010UL, 0x00000000UL,
|
||||
0x20404000UL, 0x20000000UL, 0x00400010UL, 0x20004010UL
|
||||
};
|
||||
|
||||
static const u32 SP7[64] =
|
||||
{
|
||||
0x00200000UL, 0x04200002UL, 0x04000802UL, 0x00000000UL,
|
||||
0x00000800UL, 0x04000802UL, 0x00200802UL, 0x04200800UL,
|
||||
0x04200802UL, 0x00200000UL, 0x00000000UL, 0x04000002UL,
|
||||
0x00000002UL, 0x04000000UL, 0x04200002UL, 0x00000802UL,
|
||||
0x04000800UL, 0x00200802UL, 0x00200002UL, 0x04000800UL,
|
||||
0x04000002UL, 0x04200000UL, 0x04200800UL, 0x00200002UL,
|
||||
0x04200000UL, 0x00000800UL, 0x00000802UL, 0x04200802UL,
|
||||
0x00200800UL, 0x00000002UL, 0x04000000UL, 0x00200800UL,
|
||||
0x04000000UL, 0x00200800UL, 0x00200000UL, 0x04000802UL,
|
||||
0x04000802UL, 0x04200002UL, 0x04200002UL, 0x00000002UL,
|
||||
0x00200002UL, 0x04000000UL, 0x04000800UL, 0x00200000UL,
|
||||
0x04200800UL, 0x00000802UL, 0x00200802UL, 0x04200800UL,
|
||||
0x00000802UL, 0x04000002UL, 0x04200802UL, 0x04200000UL,
|
||||
0x00200800UL, 0x00000000UL, 0x00000002UL, 0x04200802UL,
|
||||
0x00000000UL, 0x00200802UL, 0x04200000UL, 0x00000800UL,
|
||||
0x04000002UL, 0x04000800UL, 0x00000800UL, 0x00200002UL
|
||||
};
|
||||
|
||||
static const u32 SP8[64] =
|
||||
{
|
||||
0x10001040UL, 0x00001000UL, 0x00040000UL, 0x10041040UL,
|
||||
0x10000000UL, 0x10001040UL, 0x00000040UL, 0x10000000UL,
|
||||
0x00040040UL, 0x10040000UL, 0x10041040UL, 0x00041000UL,
|
||||
0x10041000UL, 0x00041040UL, 0x00001000UL, 0x00000040UL,
|
||||
0x10040000UL, 0x10000040UL, 0x10001000UL, 0x00001040UL,
|
||||
0x00041000UL, 0x00040040UL, 0x10040040UL, 0x10041000UL,
|
||||
0x00001040UL, 0x00000000UL, 0x00000000UL, 0x10040040UL,
|
||||
0x10000040UL, 0x10001000UL, 0x00041040UL, 0x00040000UL,
|
||||
0x00041040UL, 0x00040000UL, 0x10041000UL, 0x00001000UL,
|
||||
0x00000040UL, 0x10040040UL, 0x00001000UL, 0x00041040UL,
|
||||
0x10001000UL, 0x00000040UL, 0x10000040UL, 0x10040000UL,
|
||||
0x10040040UL, 0x10000000UL, 0x00040000UL, 0x10001040UL,
|
||||
0x00000000UL, 0x10041040UL, 0x00040040UL, 0x10000040UL,
|
||||
0x10040000UL, 0x10001000UL, 0x10001040UL, 0x00000000UL,
|
||||
0x10041040UL, 0x00041000UL, 0x00041000UL, 0x00001040UL,
|
||||
0x00001040UL, 0x00040040UL, 0x10000000UL, 0x10041000UL
|
||||
};
|
||||
|
||||
static void cookey(const u32 *raw1, u32 *keyout)
|
||||
{
|
||||
u32 *cook;
|
||||
const u32 *raw0;
|
||||
u32 dough[32];
|
||||
int i;
|
||||
|
||||
cook = dough;
|
||||
for (i = 0; i < 16; i++, raw1++) {
|
||||
raw0 = raw1++;
|
||||
*cook = (*raw0 & 0x00fc0000L) << 6;
|
||||
*cook |= (*raw0 & 0x00000fc0L) << 10;
|
||||
*cook |= (*raw1 & 0x00fc0000L) >> 10;
|
||||
*cook++ |= (*raw1 & 0x00000fc0L) >> 6;
|
||||
*cook = (*raw0 & 0x0003f000L) << 12;
|
||||
*cook |= (*raw0 & 0x0000003fL) << 16;
|
||||
*cook |= (*raw1 & 0x0003f000L) >> 4;
|
||||
*cook++ |= (*raw1 & 0x0000003fL);
|
||||
}
|
||||
|
||||
os_memcpy(keyout, dough, sizeof(dough));
|
||||
}
|
||||
|
||||
|
||||
static void deskey(const u8 *key, int decrypt, u32 *keyout)
|
||||
{
|
||||
u32 i, j, l, m, n, kn[32];
|
||||
u8 pc1m[56], pcr[56];
|
||||
|
||||
for (j = 0; j < 56; j++) {
|
||||
l = (u32) pc1[j];
|
||||
m = l & 7;
|
||||
pc1m[j] = (u8)
|
||||
((key[l >> 3U] & bytebit[m]) == bytebit[m] ? 1 : 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (decrypt)
|
||||
m = (15 - i) << 1;
|
||||
else
|
||||
m = i << 1;
|
||||
n = m + 1;
|
||||
kn[m] = kn[n] = 0L;
|
||||
for (j = 0; j < 28; j++) {
|
||||
l = j + (u32) totrot[i];
|
||||
if (l < 28)
|
||||
pcr[j] = pc1m[l];
|
||||
else
|
||||
pcr[j] = pc1m[l - 28];
|
||||
}
|
||||
for (/* j = 28 */; j < 56; j++) {
|
||||
l = j + (u32) totrot[i];
|
||||
if (l < 56)
|
||||
pcr[j] = pc1m[l];
|
||||
else
|
||||
pcr[j] = pc1m[l - 28];
|
||||
}
|
||||
for (j = 0; j < 24; j++) {
|
||||
if ((int) pcr[(int) pc2[j]] != 0)
|
||||
kn[m] |= bigbyte[j];
|
||||
if ((int) pcr[(int) pc2[j + 24]] != 0)
|
||||
kn[n] |= bigbyte[j];
|
||||
}
|
||||
}
|
||||
|
||||
cookey(kn, keyout);
|
||||
}
|
||||
|
||||
|
||||
static void desfunc(u32 *block, const u32 *keys)
|
||||
{
|
||||
u32 work, right, leftt;
|
||||
int cur_round;
|
||||
|
||||
leftt = block[0];
|
||||
right = block[1];
|
||||
|
||||
work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
|
||||
right ^= work;
|
||||
leftt ^= (work << 4);
|
||||
|
||||
work = ((leftt >> 16) ^ right) & 0x0000ffffL;
|
||||
right ^= work;
|
||||
leftt ^= (work << 16);
|
||||
|
||||
work = ((right >> 2) ^ leftt) & 0x33333333L;
|
||||
leftt ^= work;
|
||||
right ^= (work << 2);
|
||||
|
||||
work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
|
||||
leftt ^= work;
|
||||
right ^= (work << 8);
|
||||
|
||||
right = ROLc(right, 1);
|
||||
work = (leftt ^ right) & 0xaaaaaaaaL;
|
||||
|
||||
leftt ^= work;
|
||||
right ^= work;
|
||||
leftt = ROLc(leftt, 1);
|
||||
|
||||
for (cur_round = 0; cur_round < 8; cur_round++) {
|
||||
work = RORc(right, 4) ^ *keys++;
|
||||
leftt ^= SP7[work & 0x3fL]
|
||||
^ SP5[(work >> 8) & 0x3fL]
|
||||
^ SP3[(work >> 16) & 0x3fL]
|
||||
^ SP1[(work >> 24) & 0x3fL];
|
||||
work = right ^ *keys++;
|
||||
leftt ^= SP8[ work & 0x3fL]
|
||||
^ SP6[(work >> 8) & 0x3fL]
|
||||
^ SP4[(work >> 16) & 0x3fL]
|
||||
^ SP2[(work >> 24) & 0x3fL];
|
||||
|
||||
work = RORc(leftt, 4) ^ *keys++;
|
||||
right ^= SP7[ work & 0x3fL]
|
||||
^ SP5[(work >> 8) & 0x3fL]
|
||||
^ SP3[(work >> 16) & 0x3fL]
|
||||
^ SP1[(work >> 24) & 0x3fL];
|
||||
work = leftt ^ *keys++;
|
||||
right ^= SP8[ work & 0x3fL]
|
||||
^ SP6[(work >> 8) & 0x3fL]
|
||||
^ SP4[(work >> 16) & 0x3fL]
|
||||
^ SP2[(work >> 24) & 0x3fL];
|
||||
}
|
||||
|
||||
right = RORc(right, 1);
|
||||
work = (leftt ^ right) & 0xaaaaaaaaL;
|
||||
leftt ^= work;
|
||||
right ^= work;
|
||||
leftt = RORc(leftt, 1);
|
||||
work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
|
||||
right ^= work;
|
||||
leftt ^= (work << 8);
|
||||
/* -- */
|
||||
work = ((leftt >> 2) ^ right) & 0x33333333L;
|
||||
right ^= work;
|
||||
leftt ^= (work << 2);
|
||||
work = ((right >> 16) ^ leftt) & 0x0000ffffL;
|
||||
leftt ^= work;
|
||||
right ^= (work << 16);
|
||||
work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
|
||||
leftt ^= work;
|
||||
right ^= (work << 4);
|
||||
|
||||
block[0] = right;
|
||||
block[1] = leftt;
|
||||
}
|
||||
|
||||
|
||||
/* wpa_supplicant/hostapd specific wrapper */
|
||||
|
||||
void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
|
||||
{
|
||||
u8 pkey[8], next, tmp;
|
||||
int i;
|
||||
u32 ek[32], work[2];
|
||||
|
||||
/* Add parity bits to the key */
|
||||
next = 0;
|
||||
for (i = 0; i < 7; i++) {
|
||||
tmp = key[i];
|
||||
pkey[i] = (tmp >> i) | next | 1;
|
||||
next = tmp << (7 - i);
|
||||
}
|
||||
pkey[i] = next | 1;
|
||||
|
||||
deskey(pkey, 0, ek);
|
||||
|
||||
work[0] = WPA_GET_BE32(clear);
|
||||
work[1] = WPA_GET_BE32(clear + 4);
|
||||
desfunc(work, ek);
|
||||
WPA_PUT_BE32(cypher, work[0]);
|
||||
WPA_PUT_BE32(cypher + 4, work[1]);
|
||||
|
||||
os_memset(pkey, 0, sizeof(pkey));
|
||||
os_memset(ek, 0, sizeof(ek));
|
||||
}
|
||||
|
||||
/*
|
||||
void des_key_setup(const u8 *key, u32 *ek, u32 *dk)
|
||||
{
|
||||
deskey(key, 0, ek);
|
||||
deskey(key, 1, dk);
|
||||
}
|
||||
|
||||
|
||||
void des_block_encrypt(const u8 *plain, const u32 *ek, u8 *crypt)
|
||||
{
|
||||
u32 work[2];
|
||||
work[0] = WPA_GET_BE32(plain);
|
||||
work[1] = WPA_GET_BE32(plain + 4);
|
||||
desfunc(work, ek);
|
||||
WPA_PUT_BE32(crypt, work[0]);
|
||||
WPA_PUT_BE32(crypt + 4, work[1]);
|
||||
}
|
||||
|
||||
|
||||
void des_block_decrypt(const u8 *crypt, const u32 *dk, u8 *plain)
|
||||
{
|
||||
u32 work[2];
|
||||
work[0] = WPA_GET_BE32(crypt);
|
||||
work[1] = WPA_GET_BE32(crypt + 4);
|
||||
desfunc(work, dk);
|
||||
WPA_PUT_BE32(plain, work[0]);
|
||||
WPA_PUT_BE32(plain + 4, work[1]);
|
||||
}
|
||||
|
||||
|
||||
void des3_key_setup(const u8 *key, struct des3_key_s *dkey)
|
||||
{
|
||||
deskey(key, 0, dkey->ek[0]);
|
||||
deskey(key + 8, 1, dkey->ek[1]);
|
||||
deskey(key + 16, 0, dkey->ek[2]);
|
||||
|
||||
deskey(key, 1, dkey->dk[2]);
|
||||
deskey(key + 8, 0, dkey->dk[1]);
|
||||
deskey(key + 16, 1, dkey->dk[0]);
|
||||
}
|
||||
|
||||
|
||||
void des3_encrypt(const u8 *plain, const struct des3_key_s *key, u8 *crypt)
|
||||
{
|
||||
u32 work[2];
|
||||
|
||||
work[0] = WPA_GET_BE32(plain);
|
||||
work[1] = WPA_GET_BE32(plain + 4);
|
||||
desfunc(work, key->ek[0]);
|
||||
desfunc(work, key->ek[1]);
|
||||
desfunc(work, key->ek[2]);
|
||||
WPA_PUT_BE32(crypt, work[0]);
|
||||
WPA_PUT_BE32(crypt + 4, work[1]);
|
||||
}
|
||||
|
||||
|
||||
void des3_decrypt(const u8 *crypt, const struct des3_key_s *key, u8 *plain)
|
||||
{
|
||||
u32 work[2];
|
||||
|
||||
work[0] = WPA_GET_BE32(crypt);
|
||||
work[1] = WPA_GET_BE32(crypt + 4);
|
||||
desfunc(work, key->dk[0]);
|
||||
desfunc(work, key->dk[1]);
|
||||
desfunc(work, key->dk[2]);
|
||||
WPA_PUT_BE32(plain, work[0]);
|
||||
WPA_PUT_BE32(plain + 4, work[1]);
|
||||
}*/
|
||||
|
201
components/wpa_supplicant/src/crypto/md4-internal.c
Normal file
201
components/wpa_supplicant/src/crypto/md4-internal.c
Normal file
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* MD4 hash implementation
|
||||
*
|
||||
* This software may be distributed under the terms of BSD license.
|
||||
*/
|
||||
|
||||
#include "crypto/includes.h"
|
||||
#include "crypto/common.h"
|
||||
#include "crypto/crypto.h"
|
||||
|
||||
#define MD4_BLOCK_LENGTH 64
|
||||
#define MD4_DIGEST_LENGTH 16
|
||||
|
||||
typedef struct MD4Context {
|
||||
u32 state[4];
|
||||
u64 count;
|
||||
u8 buffer[MD4_BLOCK_LENGTH];
|
||||
} MD4_CTX;
|
||||
|
||||
static void MD4Init(MD4_CTX *ctx);
|
||||
static void MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len);
|
||||
static void MD4Final(unsigned char digest[MD4_DIGEST_LENGTH], MD4_CTX *ctx);
|
||||
|
||||
int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
|
||||
{
|
||||
MD4_CTX ctx;
|
||||
size_t i;
|
||||
|
||||
MD4Init(&ctx);
|
||||
for (i = 0; i < num_elem; i++)
|
||||
MD4Update(&ctx, addr[i], len[i]);
|
||||
MD4Final(mac, &ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MD4_DIGEST_STRING_LENGTH (MD4_DIGEST_LENGTH * 2 + 1)
|
||||
|
||||
static void MD4Transform(u32 state[4], const u8 block[MD4_BLOCK_LENGTH]);
|
||||
|
||||
#define PUT_64BIT_LE(cp, value) do { \
|
||||
(cp)[7] = (value) >> 56; \
|
||||
(cp)[6] = (value) >> 48; \
|
||||
(cp)[5] = (value) >> 40; \
|
||||
(cp)[4] = (value) >> 32; \
|
||||
(cp)[3] = (value) >> 24; \
|
||||
(cp)[2] = (value) >> 16; \
|
||||
(cp)[1] = (value) >> 8; \
|
||||
(cp)[0] = (value); } while (0)
|
||||
|
||||
#define PUT_32BIT_LE(cp, value) do { \
|
||||
(cp)[3] = (value) >> 24; \
|
||||
(cp)[2] = (value) >> 16; \
|
||||
(cp)[1] = (value) >> 8; \
|
||||
(cp)[0] = (value); } while (0)
|
||||
|
||||
static u8 PADDING[MD4_BLOCK_LENGTH] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static void MD4Init(MD4_CTX *ctx)
|
||||
{
|
||||
ctx->count = 0;
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xefcdab89;
|
||||
ctx->state[2] = 0x98badcfe;
|
||||
ctx->state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
static void MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len)
|
||||
{
|
||||
size_t have, need;
|
||||
|
||||
have = (size_t)((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1));
|
||||
need = MD4_BLOCK_LENGTH - have;
|
||||
|
||||
ctx->count += (u64)len << 3;
|
||||
|
||||
if (len >= need) {
|
||||
if (have != 0) {
|
||||
os_memcpy(ctx->buffer + have, input, need);
|
||||
MD4Transform(ctx->state, ctx->buffer);
|
||||
input += need;
|
||||
len -= need;
|
||||
have = 0;
|
||||
}
|
||||
|
||||
while (len >= MD4_BLOCK_LENGTH) {
|
||||
MD4Transform(ctx->state, input);
|
||||
input += MD4_BLOCK_LENGTH;
|
||||
len -= MD4_BLOCK_LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
if (len != 0)
|
||||
os_memcpy(ctx->buffer + have, input, len);
|
||||
}
|
||||
|
||||
static void MD4Pad(MD4_CTX *ctx)
|
||||
{
|
||||
u8 count[8];
|
||||
size_t padlen;
|
||||
|
||||
PUT_64BIT_LE(count, ctx->count);
|
||||
|
||||
padlen = MD4_BLOCK_LENGTH -
|
||||
((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1));
|
||||
if (padlen < 1 + 8)
|
||||
padlen += MD4_BLOCK_LENGTH;
|
||||
MD4Update(ctx, PADDING, padlen - 8);
|
||||
MD4Update(ctx, count, 8);
|
||||
}
|
||||
|
||||
static void MD4Final(unsigned char digest[MD4_DIGEST_LENGTH], MD4_CTX *ctx)
|
||||
{
|
||||
int i;
|
||||
|
||||
MD4Pad(ctx);
|
||||
if (digest != NULL) {
|
||||
for (i = 0; i < 4; i ++)
|
||||
PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
|
||||
os_memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
}
|
||||
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) ((x & y) | (x & z) | (y & z))
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
|
||||
#define MD4SETP(f, w, x, y, z, data, s) \
|
||||
( w += f(x, y, z) + data, w = w<<s | w>>(32-s) )
|
||||
|
||||
static void MD4Transform(u32 state[4], const u8 block[MD4_BLOCK_LENGTH])
|
||||
{
|
||||
u32 a, b, c, d, in[MD4_BLOCK_LENGTH / 4];
|
||||
|
||||
os_memcpy(in, block, sizeof(in));
|
||||
|
||||
a = state[0];
|
||||
b = state[1];
|
||||
c = state[2];
|
||||
d = state[3];
|
||||
|
||||
MD4SETP(F1, a, b, c, d, in[ 0], 3);
|
||||
MD4SETP(F1, d, a, b, c, in[ 1], 7);
|
||||
MD4SETP(F1, c, d, a, b, in[ 2], 11);
|
||||
MD4SETP(F1, b, c, d, a, in[ 3], 19);
|
||||
MD4SETP(F1, a, b, c, d, in[ 4], 3);
|
||||
MD4SETP(F1, d, a, b, c, in[ 5], 7);
|
||||
MD4SETP(F1, c, d, a, b, in[ 6], 11);
|
||||
MD4SETP(F1, b, c, d, a, in[ 7], 19);
|
||||
MD4SETP(F1, a, b, c, d, in[ 8], 3);
|
||||
MD4SETP(F1, d, a, b, c, in[ 9], 7);
|
||||
MD4SETP(F1, c, d, a, b, in[10], 11);
|
||||
MD4SETP(F1, b, c, d, a, in[11], 19);
|
||||
MD4SETP(F1, a, b, c, d, in[12], 3);
|
||||
MD4SETP(F1, d, a, b, c, in[13], 7);
|
||||
MD4SETP(F1, c, d, a, b, in[14], 11);
|
||||
MD4SETP(F1, b, c, d, a, in[15], 19);
|
||||
|
||||
MD4SETP(F2, a, b, c, d, in[ 0] + 0x5a827999, 3);
|
||||
MD4SETP(F2, d, a, b, c, in[ 4] + 0x5a827999, 5);
|
||||
MD4SETP(F2, c, d, a, b, in[ 8] + 0x5a827999, 9);
|
||||
MD4SETP(F2, b, c, d, a, in[12] + 0x5a827999, 13);
|
||||
MD4SETP(F2, a, b, c, d, in[ 1] + 0x5a827999, 3);
|
||||
MD4SETP(F2, d, a, b, c, in[ 5] + 0x5a827999, 5);
|
||||
MD4SETP(F2, c, d, a, b, in[ 9] + 0x5a827999, 9);
|
||||
MD4SETP(F2, b, c, d, a, in[13] + 0x5a827999, 13);
|
||||
MD4SETP(F2, a, b, c, d, in[ 2] + 0x5a827999, 3);
|
||||
MD4SETP(F2, d, a, b, c, in[ 6] + 0x5a827999, 5);
|
||||
MD4SETP(F2, c, d, a, b, in[10] + 0x5a827999, 9);
|
||||
MD4SETP(F2, b, c, d, a, in[14] + 0x5a827999, 13);
|
||||
MD4SETP(F2, a, b, c, d, in[ 3] + 0x5a827999, 3);
|
||||
MD4SETP(F2, d, a, b, c, in[ 7] + 0x5a827999, 5);
|
||||
MD4SETP(F2, c, d, a, b, in[11] + 0x5a827999, 9);
|
||||
MD4SETP(F2, b, c, d, a, in[15] + 0x5a827999, 13);
|
||||
|
||||
MD4SETP(F3, a, b, c, d, in[ 0] + 0x6ed9eba1, 3);
|
||||
MD4SETP(F3, d, a, b, c, in[ 8] + 0x6ed9eba1, 9);
|
||||
MD4SETP(F3, c, d, a, b, in[ 4] + 0x6ed9eba1, 11);
|
||||
MD4SETP(F3, b, c, d, a, in[12] + 0x6ed9eba1, 15);
|
||||
MD4SETP(F3, a, b, c, d, in[ 2] + 0x6ed9eba1, 3);
|
||||
MD4SETP(F3, d, a, b, c, in[10] + 0x6ed9eba1, 9);
|
||||
MD4SETP(F3, c, d, a, b, in[ 6] + 0x6ed9eba1, 11);
|
||||
MD4SETP(F3, b, c, d, a, in[14] + 0x6ed9eba1, 15);
|
||||
MD4SETP(F3, a, b, c, d, in[ 1] + 0x6ed9eba1, 3);
|
||||
MD4SETP(F3, d, a, b, c, in[ 9] + 0x6ed9eba1, 9);
|
||||
MD4SETP(F3, c, d, a, b, in[ 5] + 0x6ed9eba1, 11);
|
||||
MD4SETP(F3, b, c, d, a, in[13] + 0x6ed9eba1, 15);
|
||||
MD4SETP(F3, a, b, c, d, in[ 3] + 0x6ed9eba1, 3);
|
||||
MD4SETP(F3, d, a, b, c, in[11] + 0x6ed9eba1, 9);
|
||||
MD4SETP(F3, c, d, a, b, in[ 7] + 0x6ed9eba1, 11);
|
||||
MD4SETP(F3, b, c, d, a, in[15] + 0x6ed9eba1, 15);
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
}
|
528
components/wpa_supplicant/src/crypto/ms_funcs.c
Normal file
528
components/wpa_supplicant/src/crypto/ms_funcs.c
Normal file
@ -0,0 +1,528 @@
|
||||
/*
|
||||
* WPA Supplicant / shared MSCHAPV2 helper functions / RFC 2433 / RFC 2759
|
||||
* Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include "wpa/includes.h"
|
||||
|
||||
#include "wpa/common.h"
|
||||
#include "crypto/sha1.h"
|
||||
#include "crypto/ms_funcs.h"
|
||||
#include "crypto/crypto.h"
|
||||
|
||||
/**
|
||||
* utf8_to_ucs2 - Convert UTF-8 string to UCS-2 encoding
|
||||
* @utf8_string: UTF-8 string (IN)
|
||||
* @utf8_string_len: Length of utf8_string (IN)
|
||||
* @ucs2_buffer: UCS-2 buffer (OUT)
|
||||
* @ucs2_buffer_size: Length of UCS-2 buffer (IN)
|
||||
* @ucs2_string_size: Number of 2-byte words in the resulting UCS-2 string
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
static int utf8_to_ucs2(const u8 *utf8_string, size_t utf8_string_len,
|
||||
u8 *ucs2_buffer, size_t ucs2_buffer_size,
|
||||
size_t *ucs2_string_size)
|
||||
{
|
||||
size_t i, j;
|
||||
|
||||
for (i = 0, j = 0; i < utf8_string_len; i++) {
|
||||
u8 c = utf8_string[i];
|
||||
if (j >= ucs2_buffer_size) {
|
||||
/* input too long */
|
||||
return -1;
|
||||
}
|
||||
if (c <= 0x7F) {
|
||||
WPA_PUT_LE16(ucs2_buffer + j, c);
|
||||
j += 2;
|
||||
} else if (i == utf8_string_len - 1 ||
|
||||
j >= ucs2_buffer_size - 1) {
|
||||
/* incomplete surrogate */
|
||||
return -1;
|
||||
} else {
|
||||
u8 c2 = utf8_string[++i];
|
||||
if ((c & 0xE0) == 0xC0) {
|
||||
/* two-byte encoding */
|
||||
WPA_PUT_LE16(ucs2_buffer + j,
|
||||
((c & 0x1F) << 6) | (c2 & 0x3F));
|
||||
j += 2;
|
||||
} else if (i == utf8_string_len ||
|
||||
j >= ucs2_buffer_size - 1) {
|
||||
/* incomplete surrogate */
|
||||
return -1;
|
||||
} else {
|
||||
/* three-byte encoding */
|
||||
u8 c3 = utf8_string[++i];
|
||||
WPA_PUT_LE16(ucs2_buffer + j,
|
||||
((c & 0xF) << 12) |
|
||||
((c2 & 0x3F) << 6) | (c3 & 0x3F));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ucs2_string_size)
|
||||
*ucs2_string_size = j / 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* challenge_hash - ChallengeHash() - RFC 2759, Sect. 8.2
|
||||
* @peer_challenge: 16-octet PeerChallenge (IN)
|
||||
* @auth_challenge: 16-octet AuthenticatorChallenge (IN)
|
||||
* @username: 0-to-256-char UserName (IN)
|
||||
* @username_len: Length of username
|
||||
* @challenge: 8-octet Challenge (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
static int challenge_hash(const u8 *peer_challenge, const u8 *auth_challenge,
|
||||
const u8 *username, size_t username_len,
|
||||
u8 *challenge)
|
||||
{
|
||||
u8 hash[SHA1_MAC_LEN];
|
||||
const unsigned char *addr[3];
|
||||
size_t len[3];
|
||||
|
||||
addr[0] = peer_challenge;
|
||||
len[0] = 16;
|
||||
addr[1] = auth_challenge;
|
||||
len[1] = 16;
|
||||
addr[2] = username;
|
||||
len[2] = username_len;
|
||||
|
||||
if (sha1_vector(3, addr, len, hash))
|
||||
return -1;
|
||||
os_memcpy(challenge, hash, 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* nt_password_hash - NtPasswordHash() - RFC 2759, Sect. 8.3
|
||||
* @password: 0-to-256-unicode-char Password (IN; UTF-8)
|
||||
* @password_len: Length of password
|
||||
* @password_hash: 16-octet PasswordHash (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int nt_password_hash(const u8 *password, size_t password_len,
|
||||
u8 *password_hash)
|
||||
{
|
||||
u8 buf[512], *pos;
|
||||
size_t len, max_len;
|
||||
|
||||
max_len = sizeof(buf);
|
||||
if (utf8_to_ucs2(password, password_len, buf, max_len, &len) < 0)
|
||||
return -1;
|
||||
|
||||
len *= 2;
|
||||
pos = buf;
|
||||
return md4_vector(1, (const u8 **) &pos, &len, password_hash);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hash_nt_password_hash - HashNtPasswordHash() - RFC 2759, Sect. 8.4
|
||||
* @password_hash: 16-octet PasswordHash (IN)
|
||||
* @password_hash_hash: 16-octet PasswordHashHash (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int hash_nt_password_hash(const u8 *password_hash, u8 *password_hash_hash)
|
||||
{
|
||||
size_t len = 16;
|
||||
return md4_vector(1, &password_hash, &len, password_hash_hash);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* challenge_response - ChallengeResponse() - RFC 2759, Sect. 8.5
|
||||
* @challenge: 8-octet Challenge (IN)
|
||||
* @password_hash: 16-octet PasswordHash (IN)
|
||||
* @response: 24-octet Response (OUT)
|
||||
*/
|
||||
void challenge_response(const u8 *challenge, const u8 *password_hash,
|
||||
u8 *response)
|
||||
{
|
||||
u8 zpwd[7];
|
||||
des_encrypt(challenge, password_hash, response);
|
||||
des_encrypt(challenge, password_hash + 7, response + 8);
|
||||
zpwd[0] = password_hash[14];
|
||||
zpwd[1] = password_hash[15];
|
||||
os_memset(zpwd + 2, 0, 5);
|
||||
des_encrypt(challenge, zpwd, response + 16);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* generate_nt_response - GenerateNTResponse() - RFC 2759, Sect. 8.1
|
||||
* @auth_challenge: 16-octet AuthenticatorChallenge (IN)
|
||||
* @peer_challenge: 16-octet PeerChallenge (IN)
|
||||
* @username: 0-to-256-char UserName (IN)
|
||||
* @username_len: Length of username
|
||||
* @password: 0-to-256-unicode-char Password (IN; UTF-8)
|
||||
* @password_len: Length of password
|
||||
* @response: 24-octet Response (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int generate_nt_response(const u8 *auth_challenge, const u8 *peer_challenge,
|
||||
const u8 *username, size_t username_len,
|
||||
const u8 *password, size_t password_len,
|
||||
u8 *response)
|
||||
{
|
||||
u8 challenge[8];
|
||||
u8 password_hash[16];
|
||||
|
||||
if (challenge_hash(peer_challenge, auth_challenge, username,
|
||||
username_len, challenge))
|
||||
return -1;
|
||||
if (nt_password_hash(password, password_len, password_hash))
|
||||
return -1;
|
||||
challenge_response(challenge, password_hash, response);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* generate_nt_response_pwhash - GenerateNTResponse() - RFC 2759, Sect. 8.1
|
||||
* @auth_challenge: 16-octet AuthenticatorChallenge (IN)
|
||||
* @peer_challenge: 16-octet PeerChallenge (IN)
|
||||
* @username: 0-to-256-char UserName (IN)
|
||||
* @username_len: Length of username
|
||||
* @password_hash: 16-octet PasswordHash (IN)
|
||||
* @response: 24-octet Response (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int generate_nt_response_pwhash(const u8 *auth_challenge,
|
||||
const u8 *peer_challenge,
|
||||
const u8 *username, size_t username_len,
|
||||
const u8 *password_hash,
|
||||
u8 *response)
|
||||
{
|
||||
u8 challenge[8];
|
||||
|
||||
if (challenge_hash(peer_challenge, auth_challenge,
|
||||
username, username_len,
|
||||
challenge))
|
||||
return -1;
|
||||
challenge_response(challenge, password_hash, response);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* generate_authenticator_response_pwhash - GenerateAuthenticatorResponse() - RFC 2759, Sect. 8.7
|
||||
* @password_hash: 16-octet PasswordHash (IN)
|
||||
* @nt_response: 24-octet NT-Response (IN)
|
||||
* @peer_challenge: 16-octet PeerChallenge (IN)
|
||||
* @auth_challenge: 16-octet AuthenticatorChallenge (IN)
|
||||
* @username: 0-to-256-char UserName (IN)
|
||||
* @username_len: Length of username
|
||||
* @response: 20-octet AuthenticatorResponse (OUT) (note: this value is usually
|
||||
* encoded as a 42-octet ASCII string (S=hexdump_of_response)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int generate_authenticator_response_pwhash(
|
||||
const u8 *password_hash,
|
||||
const u8 *peer_challenge, const u8 *auth_challenge,
|
||||
const u8 *username, size_t username_len,
|
||||
const u8 *nt_response, u8 *response)
|
||||
{
|
||||
static const u8 magic1[39] = {
|
||||
0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
|
||||
0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
|
||||
0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
|
||||
0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74
|
||||
};
|
||||
static const u8 magic2[41] = {
|
||||
0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
|
||||
0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
|
||||
0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,
|
||||
0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
|
||||
0x6E
|
||||
};
|
||||
|
||||
u8 password_hash_hash[16], challenge[8];
|
||||
const unsigned char *addr1[3];
|
||||
const size_t len1[3] = { 16, 24, sizeof(magic1) };
|
||||
const unsigned char *addr2[3];
|
||||
const size_t len2[3] = { SHA1_MAC_LEN, 8, sizeof(magic2) };
|
||||
|
||||
addr1[0] = password_hash_hash;
|
||||
addr1[1] = nt_response;
|
||||
addr1[2] = magic1;
|
||||
|
||||
addr2[0] = response;
|
||||
addr2[1] = challenge;
|
||||
addr2[2] = magic2;
|
||||
|
||||
if (hash_nt_password_hash(password_hash, password_hash_hash))
|
||||
return -1;
|
||||
if (sha1_vector(3, addr1, len1, response))
|
||||
return -1;
|
||||
|
||||
if (challenge_hash(peer_challenge, auth_challenge, username,
|
||||
username_len, challenge))
|
||||
return -1;
|
||||
return sha1_vector(3, addr2, len2, response);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* generate_authenticator_response - GenerateAuthenticatorResponse() - RFC 2759, Sect. 8.7
|
||||
* @password: 0-to-256-unicode-char Password (IN; UTF-8)
|
||||
* @password_len: Length of password
|
||||
* @nt_response: 24-octet NT-Response (IN)
|
||||
* @peer_challenge: 16-octet PeerChallenge (IN)
|
||||
* @auth_challenge: 16-octet AuthenticatorChallenge (IN)
|
||||
* @username: 0-to-256-char UserName (IN)
|
||||
* @username_len: Length of username
|
||||
* @response: 20-octet AuthenticatorResponse (OUT) (note: this value is usually
|
||||
* encoded as a 42-octet ASCII string (S=hexdump_of_response)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int generate_authenticator_response(const u8 *password, size_t password_len,
|
||||
const u8 *peer_challenge,
|
||||
const u8 *auth_challenge,
|
||||
const u8 *username, size_t username_len,
|
||||
const u8 *nt_response, u8 *response)
|
||||
{
|
||||
u8 password_hash[16];
|
||||
if (nt_password_hash(password, password_len, password_hash))
|
||||
return -1;
|
||||
return generate_authenticator_response_pwhash(
|
||||
password_hash, peer_challenge, auth_challenge,
|
||||
username, username_len, nt_response, response);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* nt_challenge_response - NtChallengeResponse() - RFC 2433, Sect. A.5
|
||||
* @challenge: 8-octet Challenge (IN)
|
||||
* @password: 0-to-256-unicode-char Password (IN; UTF-8)
|
||||
* @password_len: Length of password
|
||||
* @response: 24-octet Response (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int nt_challenge_response(const u8 *challenge, const u8 *password,
|
||||
size_t password_len, u8 *response)
|
||||
{
|
||||
u8 password_hash[16];
|
||||
if (nt_password_hash(password, password_len, password_hash))
|
||||
return -1;
|
||||
challenge_response(challenge, password_hash, response);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get_master_key - GetMasterKey() - RFC 3079, Sect. 3.4
|
||||
* @password_hash_hash: 16-octet PasswordHashHash (IN)
|
||||
* @nt_response: 24-octet NTResponse (IN)
|
||||
* @master_key: 16-octet MasterKey (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int get_master_key(const u8 *password_hash_hash, const u8 *nt_response,
|
||||
u8 *master_key)
|
||||
{
|
||||
static const u8 magic1[27] = {
|
||||
0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,
|
||||
0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d,
|
||||
0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79
|
||||
};
|
||||
const unsigned char *addr[3];
|
||||
const size_t len[3] = { 16, 24, sizeof(magic1) };
|
||||
u8 hash[SHA1_MAC_LEN];
|
||||
|
||||
addr[0] = password_hash_hash;
|
||||
addr[1] = nt_response;
|
||||
addr[2] = magic1;
|
||||
|
||||
if (sha1_vector(3, addr, len, hash))
|
||||
return -1;
|
||||
os_memcpy(master_key, hash, 16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get_asymetric_start_key - GetAsymetricStartKey() - RFC 3079, Sect. 3.4
|
||||
* @master_key: 16-octet MasterKey (IN)
|
||||
* @session_key: 8-to-16 octet SessionKey (OUT)
|
||||
* @session_key_len: SessionKeyLength (Length of session_key) (IN)
|
||||
* @is_send: IsSend (IN, BOOLEAN)
|
||||
* @is_server: IsServer (IN, BOOLEAN)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int get_asymetric_start_key(const u8 *master_key, u8 *session_key,
|
||||
size_t session_key_len, int is_send,
|
||||
int is_server)
|
||||
{
|
||||
static const u8 magic2[84] = {
|
||||
0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
|
||||
0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
|
||||
0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
|
||||
0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
|
||||
0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
|
||||
0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65,
|
||||
0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
|
||||
0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
|
||||
0x6b, 0x65, 0x79, 0x2e
|
||||
};
|
||||
static const u8 magic3[84] = {
|
||||
0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
|
||||
0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
|
||||
0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
|
||||
0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
|
||||
0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68,
|
||||
0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73,
|
||||
0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73,
|
||||
0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20,
|
||||
0x6b, 0x65, 0x79, 0x2e
|
||||
};
|
||||
static const u8 shs_pad1[40] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const u8 shs_pad2[40] = {
|
||||
0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
|
||||
0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
|
||||
0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
|
||||
0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2
|
||||
};
|
||||
u8 digest[SHA1_MAC_LEN];
|
||||
const unsigned char *addr[4];
|
||||
const size_t len[4] = { 16, 40, 84, 40 };
|
||||
|
||||
addr[0] = master_key;
|
||||
addr[1] = shs_pad1;
|
||||
if (is_send) {
|
||||
addr[2] = is_server ? magic3 : magic2;
|
||||
} else {
|
||||
addr[2] = is_server ? magic2 : magic3;
|
||||
}
|
||||
addr[3] = shs_pad2;
|
||||
|
||||
if (sha1_vector(4, addr, len, digest))
|
||||
return -1;
|
||||
|
||||
if (session_key_len > SHA1_MAC_LEN)
|
||||
session_key_len = SHA1_MAC_LEN;
|
||||
os_memcpy(session_key, digest, session_key_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define PWBLOCK_LEN 516
|
||||
|
||||
/**
|
||||
* encrypt_pw_block_with_password_hash - EncryptPwBlockWithPasswordHash() - RFC 2759, Sect. 8.10
|
||||
* @password: 0-to-256-unicode-char Password (IN; UTF-8)
|
||||
* @password_len: Length of password
|
||||
* @password_hash: 16-octet PasswordHash (IN)
|
||||
* @pw_block: 516-byte PwBlock (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int encrypt_pw_block_with_password_hash(
|
||||
const u8 *password, size_t password_len,
|
||||
const u8 *password_hash, u8 *pw_block)
|
||||
{
|
||||
size_t ucs2_len, offset;
|
||||
u8 *pos;
|
||||
|
||||
os_memset(pw_block, 0, PWBLOCK_LEN);
|
||||
|
||||
if (utf8_to_ucs2(password, password_len, pw_block, 512, &ucs2_len) < 0)
|
||||
return -1;
|
||||
|
||||
if (ucs2_len > 256)
|
||||
return -1;
|
||||
|
||||
offset = (256 - ucs2_len) * 2;
|
||||
if (offset != 0) {
|
||||
os_memmove(pw_block + offset, pw_block, ucs2_len * 2);
|
||||
if (os_get_random(pw_block, offset) < 0)
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* PasswordLength is 4 octets, but since the maximum password length is
|
||||
* 256, only first two (in little endian byte order) can be non-zero.
|
||||
*/
|
||||
pos = &pw_block[2 * 256];
|
||||
WPA_PUT_LE16(pos, password_len * 2);
|
||||
rc4_skip(password_hash, 16, 0, pw_block, PWBLOCK_LEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* new_password_encrypted_with_old_nt_password_hash - NewPasswordEncryptedWithOldNtPasswordHash() - RFC 2759, Sect. 8.9
|
||||
* @new_password: 0-to-256-unicode-char NewPassword (IN; UTF-8)
|
||||
* @new_password_len: Length of new_password
|
||||
* @old_password: 0-to-256-unicode-char OldPassword (IN; UTF-8)
|
||||
* @old_password_len: Length of old_password
|
||||
* @encrypted_pw_block: 516-octet EncryptedPwBlock (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int new_password_encrypted_with_old_nt_password_hash(
|
||||
const u8 *new_password, size_t new_password_len,
|
||||
const u8 *old_password, size_t old_password_len,
|
||||
u8 *encrypted_pw_block)
|
||||
{
|
||||
u8 password_hash[16];
|
||||
|
||||
if (nt_password_hash(old_password, old_password_len, password_hash))
|
||||
return -1;
|
||||
if (encrypt_pw_block_with_password_hash(new_password, new_password_len,
|
||||
password_hash,
|
||||
encrypted_pw_block))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* nt_password_hash_encrypted_with_block - NtPasswordHashEncryptedWithBlock() - RFC 2759, Sect 8.13
|
||||
* @password_hash: 16-octer PasswordHash (IN)
|
||||
* @block: 16-octet Block (IN)
|
||||
* @cypher: 16-octer Cypher (OUT)
|
||||
*/
|
||||
void nt_password_hash_encrypted_with_block(const u8 *password_hash,
|
||||
const u8 *block, u8 *cypher)
|
||||
{
|
||||
des_encrypt(password_hash, block, cypher);
|
||||
des_encrypt(password_hash + 8, block + 7, cypher + 8);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* old_nt_password_hash_encrypted_with_new_nt_password_hash - OldNtPasswordHashEncryptedWithNewNtPasswordHash() - RFC 2759, Sect. 8.12
|
||||
* @new_password: 0-to-256-unicode-char NewPassword (IN; UTF-8)
|
||||
* @new_password_len: Length of new_password
|
||||
* @old_password: 0-to-256-unicode-char OldPassword (IN; UTF-8)
|
||||
* @old_password_len: Length of old_password
|
||||
* @encrypted_password_hash: 16-octet EncryptedPasswordHash (OUT)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int old_nt_password_hash_encrypted_with_new_nt_password_hash(
|
||||
const u8 *new_password, size_t new_password_len,
|
||||
const u8 *old_password, size_t old_password_len,
|
||||
u8 *encrypted_password_hash)
|
||||
{
|
||||
u8 old_password_hash[16], new_password_hash[16];
|
||||
|
||||
if (nt_password_hash(old_password, old_password_len,
|
||||
old_password_hash) ||
|
||||
nt_password_hash(new_password, new_password_len,
|
||||
new_password_hash))
|
||||
return -1;
|
||||
nt_password_hash_encrypted_with_block(old_password_hash,
|
||||
new_password_hash,
|
||||
encrypted_password_hash);
|
||||
return 0;
|
||||
}
|
||||
|
@ -23,7 +23,8 @@ INPUT = ../components/esp32/include/esp_wifi.h \
|
||||
../components/vfs/include \
|
||||
../components/spi_flash/include \
|
||||
../components/esp32/include/esp_int_wdt.h \
|
||||
../components/esp32/include/esp_task_wdt.h
|
||||
../components/esp32/include/esp_task_wdt.h \
|
||||
../components/app_update/include/esp_ota_ops.h
|
||||
|
||||
## Get warnings for functions that have no documentation for their parameters or return value
|
||||
##
|
||||
|
46
docs/api/ota.rst
Normal file
46
docs/api/ota.rst
Normal file
@ -0,0 +1,46 @@
|
||||
OTA
|
||||
===
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
`Instructions`_
|
||||
|
||||
Application Example
|
||||
-------------------
|
||||
|
||||
`Instructions`_
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
`Instructions`_
|
||||
|
||||
.. _Instructions: template.html
|
||||
|
||||
Header Files
|
||||
^^^^^^^^^^^^
|
||||
|
||||
* `app_update/include/esp_ota_ops.h <https://github.com/espressif/esp-idf/blob/master/components/app_update/include/esp_ota_ops.h>`_
|
||||
|
||||
Macros
|
||||
------
|
||||
|
||||
.. doxygendefine:: ESP_ERR_OTA_BASE
|
||||
.. doxygendefine:: ESP_ERR_OTA_PARTITION_CONFLICT
|
||||
.. doxygendefine:: ESP_ERR_OTA_SELECT_INFO_INVALID
|
||||
.. doxygendefine:: ESP_ERR_OTA_VALIDATE_FAILED
|
||||
|
||||
Type Definitions
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
.. doxygentypedef:: esp_ota_handle_t
|
||||
|
||||
Functions
|
||||
^^^^^^^^^
|
||||
|
||||
.. doxygenfunction:: esp_ota_begin
|
||||
.. doxygenfunction:: esp_ota_write
|
||||
.. doxygenfunction:: esp_ota_end
|
||||
.. doxygenfunction:: esp_ota_set_boot_partition
|
||||
.. doxygenfunction:: esp_ota_get_boot_partition
|
66
docs/api/pcnt.rst
Normal file
66
docs/api/pcnt.rst
Normal file
@ -0,0 +1,66 @@
|
||||
Pulse Counter
|
||||
========
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The PCNT (Pulse Counter) module is designed to count the number of rising and/or falling edges of an input signal. Each pulse counter unit has a 16-bit signed counter register and two channels that can be configured to either increment or decrement the counter. Each channel has a signal input that accepts signal edges to be detected, as well as a control input that can be used to enable or disable the signal input. The inputs have optional filters that can be used to discard unwanted glitches in the signal.
|
||||
|
||||
Application Example
|
||||
-------------------
|
||||
|
||||
Pulse counter with control signal and event interrupt example: `examples/12_pcnt <https://github.com/espressif/esp-idf/tree/master/examples/12_pcnt>`_.
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
Header Files
|
||||
^^^^^^^^^^^^
|
||||
|
||||
* `driver/pcnt.h <https://github.com/espressif/esp-idf/blob/master/components/driver/include/driver/pcnt.h>`_
|
||||
|
||||
|
||||
Macros
|
||||
^^^^^^
|
||||
|
||||
|
||||
Type Definitions
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
Enumerations
|
||||
^^^^^^^^^^^^
|
||||
|
||||
.. doxygenenum:: pcnt_ctrl_mode_t
|
||||
.. doxygenenum:: pcnt_count_mode_t
|
||||
.. doxygenenum:: pcnt_unit_t
|
||||
.. doxygenenum:: pcnt_channel_t
|
||||
.. doxygenenum:: pcnt_evt_type_t
|
||||
|
||||
Structures
|
||||
^^^^^^^^^^
|
||||
|
||||
.. doxygenstruct:: pcnt_config_t
|
||||
|
||||
Functions
|
||||
^^^^^^^^^
|
||||
|
||||
.. doxygenfunction:: pcnt_unit_config
|
||||
.. doxygenfunction:: pcnt_get_counter_value
|
||||
.. doxygenfunction:: pcnt_counter_pause
|
||||
.. doxygenfunction:: pcnt_counter_resume
|
||||
.. doxygenfunction:: pcnt_counter_clear
|
||||
.. doxygenfunction:: pcnt_intr_enable
|
||||
.. doxygenfunction:: pcnt_intr_disable
|
||||
.. doxygenfunction:: pcnt_event_enable
|
||||
.. doxygenfunction:: pcnt_event_disable
|
||||
.. doxygenfunction:: pcnt_set_event_value
|
||||
.. doxygenfunction:: pcnt_get_event_value
|
||||
.. doxygenfunction:: pcnt_isr_register
|
||||
.. doxygenfunction:: pcnt_set_pin
|
||||
.. doxygenfunction:: pcnt_filter_enable
|
||||
.. doxygenfunction:: pcnt_filter_disable
|
||||
.. doxygenfunction:: pcnt_set_filter_value
|
||||
.. doxygenfunction:: pcnt_get_filter_value
|
||||
.. doxygenfunction:: pcnt_set_mode
|
||||
|
73
docs/api/timer.rst
Normal file
73
docs/api/timer.rst
Normal file
@ -0,0 +1,73 @@
|
||||
TIMER
|
||||
========
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
ESP32 chip contains two hardware timer groups, each containing two general-purpose hardware timers.
|
||||
|
||||
They are all 64-bit generic timers based on 16-bit prescalers and 64-bit auto-reload-capable up/down counters.
|
||||
|
||||
|
||||
Application Example
|
||||
-------------------
|
||||
|
||||
64-bit hardware timer example: `examples/13_timer_group <https://github.com/espressif/esp-idf/tree/master/examples/13_timer_group>`_.
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
Header Files
|
||||
^^^^^^^^^^^^
|
||||
|
||||
* `components/driver/timer.h <https://github.com/espressif/esp-idf/blob/master/components/driver/include/driver/timer.h>`_
|
||||
|
||||
Macros
|
||||
^^^^^^
|
||||
|
||||
.. doxygendefine:: TIMER_BASE_CLK
|
||||
|
||||
Type Definitions
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
Enumerations
|
||||
^^^^^^^^^^^^
|
||||
|
||||
.. doxygenenum:: timer_group_t
|
||||
.. doxygenenum:: timer_idx_t
|
||||
.. doxygenenum:: timer_count_dir_t
|
||||
.. doxygenenum:: timer_start_t
|
||||
.. doxygenenum:: timer_alarm_t
|
||||
.. doxygenenum:: timer_intr_mode_t
|
||||
.. doxygenenum:: timer_autoreload_t
|
||||
|
||||
Structures
|
||||
^^^^^^^^^^
|
||||
|
||||
.. doxygenstruct:: timer_config_t
|
||||
:members:
|
||||
|
||||
|
||||
Functions
|
||||
^^^^^^^^^
|
||||
|
||||
.. doxygenfunction:: timer_get_counter_value
|
||||
.. doxygenfunction:: timer_get_counter_time_sec
|
||||
.. doxygenfunction:: timer_set_counter_value
|
||||
.. doxygenfunction:: timer_start
|
||||
.. doxygenfunction:: timer_pause
|
||||
.. doxygenfunction:: timer_set_counter_mode
|
||||
.. doxygenfunction:: timer_set_auto_reload
|
||||
.. doxygenfunction:: timer_set_divider
|
||||
.. doxygenfunction:: timer_set_alarm_value
|
||||
.. doxygenfunction:: timer_get_alarm_value
|
||||
.. doxygenfunction:: timer_set_alarm
|
||||
.. doxygenfunction:: timer_isr_register
|
||||
.. doxygenfunction:: timer_init
|
||||
.. doxygenfunction:: timer_get_config
|
||||
.. doxygenfunction:: timer_group_intr_enable
|
||||
.. doxygenfunction:: timer_group_intr_disable
|
||||
.. doxygenfunction:: timer_enable_intr
|
||||
.. doxygenfunction:: timer_disable_intr
|
||||
|
@ -244,6 +244,7 @@ The following variables can be set inside ``component.mk`` to control the build
|
||||
settings. Component-specific additions can be made via ``CXXFLAGS
|
||||
+=``. It is also possible (although not recommended) to override
|
||||
this variable completely for a component.
|
||||
- ``FLAGS_basename`` allows you to set compilation flags to apply to a single source file only. For example, this can useful for disabling warnings in a single upstream source file. The ``basename`` portion is the directory (relative to ``COMPONENT_PATH``) and the base filename (without extension) of the source file. For example, if a file inside ``COMPONENT_PATH`` is ``library/alpha/widget.c`` then you can set variable ``FLAGS_library/alpha/widget := -DTEST`` to pass the TEST macro when compiling this source file only.
|
||||
|
||||
Component Configuration
|
||||
-----------------------
|
||||
|
@ -97,11 +97,13 @@ Contents:
|
||||
Wi-Fi <api/esp_wifi>
|
||||
Bluetooth <api/bt>
|
||||
Watchdogs <api/wdts>
|
||||
|
||||
api/gpio
|
||||
api/uart
|
||||
api/ledc
|
||||
api/rmt
|
||||
OTA <api/ota>
|
||||
GPIO <api/gpio>
|
||||
UART <api/uart>
|
||||
LED Control <api/ledc>
|
||||
Remote Control <api/rmt>
|
||||
Timer <api/timer>
|
||||
Pulse Counter <api/pcnt>
|
||||
SPI Flash and Partition APIs <api/spi_flash>
|
||||
Logging <api/log>
|
||||
Non-Volatile Storage <api/nvs_flash>
|
||||
|
@ -21,7 +21,7 @@ void hello_task(void *pvParameter)
|
||||
}
|
||||
printf("Restarting now.\n");
|
||||
fflush(stdout);
|
||||
system_restart();
|
||||
esp_restart();
|
||||
}
|
||||
|
||||
void app_main()
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user