Merge remote-tracking branch 'origin/feature/mbedtls'

This commit is contained in:
Wu Jian Gang 2016-09-14 18:05:56 +08:00
commit 2efaf42253
33 changed files with 2469 additions and 72 deletions

View file

@ -37,7 +37,7 @@ build_template_app:
# branch
- git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..."
- make defconfig
- make all
- make all V=1
.build_gitlab: &build_template

View file

@ -18,15 +18,11 @@ BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin
$(BOOTLOADER_BIN): $(COMPONENT_PATH)/src/sdkconfig
$(Q) PROJECT_PATH= \
LDFLAGS= \
CFLAGS= \
BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \
$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src MAKEFLAGS= V=$(V) TARGET_BIN_LAYOUT="$(BOOTLOADER_TARGET_BIN_LAYOUT)" $(BOOTLOADER_BIN)
bootloader-clean:
$(Q) PROJECT_PATH= \
LDFLAGS= \
CFLAGS= \
BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \
$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src app-clean MAKEFLAGS= V=$(V)

View file

@ -8,6 +8,8 @@
#
-include $(PROJECT_PATH)/build/include/config/auto.conf
COMPONENT_SRCDIRS := . hwcrypto
LIBS := crypto core net80211 phy rtc pp wpa wps
ifeq ($(CONFIG_MEMMAP_BT),y)

View file

@ -0,0 +1,354 @@
/**
* \brief AES block cipher, ESP32 hardware accelerated version
* 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.
*
*/
/*
* The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
*
* http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
*/
#include <string.h>
#include "hwcrypto/aes.h"
#include "rom/aes.h"
#include <sys/lock.h>
static _lock_t aes_lock;
void esp_aes_acquire_hardware( void )
{
/* newlib locks lazy initialize on ESP-IDF */
_lock_acquire(&aes_lock);
ets_aes_enable();
}
void esp_aes_release_hardware( void )
{
uint8_t zero[256/8] = { 0 };
ets_aes_setkey_enc(zero, AES256);
ets_aes_disable();
_lock_release(&aes_lock);
}
void esp_aes_init( esp_aes_context *ctx )
{
bzero( ctx, sizeof( esp_aes_context ) );
}
void esp_aes_free( esp_aes_context *ctx )
{
if ( ctx == NULL ) {
return;
}
bzero( ctx, sizeof( esp_aes_context ) );
}
/* Translate number of bits to an AES_BITS enum */
static int keybits_to_aesbits(unsigned int keybits)
{
switch (keybits) {
case 128:
return AES128;
case 192:
return AES192;
break;
case 256:
return AES256;
default:
return ( ERR_ESP_AES_INVALID_KEY_LENGTH );
}
}
/*
* AES key schedule (encryption)
*
*/
int esp_aes_setkey_enc( esp_aes_context *ctx, const unsigned char *key,
unsigned int keybits )
{
uint16_t keybytes = keybits / 8;
int aesbits = keybits_to_aesbits(keybits);
if (aesbits < 0) {
return aesbits;
}
ctx->enc.aesbits = aesbits;
bzero(ctx->enc.key, sizeof(ctx->enc.key));
memcpy(ctx->enc.key, key, keybytes);
return 0;
}
/*
* AES key schedule (decryption)
*
*/
int esp_aes_setkey_dec( esp_aes_context *ctx, const unsigned char *key,
unsigned int keybits )
{
uint16_t keybytes = keybits / 8;
int aesbits = keybits_to_aesbits(keybits);
if (aesbits < 0) {
return aesbits;
}
ctx->dec.aesbits = aesbits;
bzero(ctx->dec.key, sizeof(ctx->dec.key));
memcpy(ctx->dec.key, key, keybytes);
return 0;
}
/*
* Helper function to copy key from esp_aes_context buffer
* to hardware key registers.
*
* Only call when protected by esp_aes_acquire_hardware().
*/
static inline int esp_aes_setkey_hardware( esp_aes_context *ctx, int mode)
{
if ( mode == ESP_AES_ENCRYPT ) {
ets_aes_setkey_enc(ctx->enc.key, ctx->enc.aesbits);
} else {
ets_aes_setkey_dec(ctx->dec.key, ctx->dec.aesbits);
}
return 0;
}
/*
* AES-ECB block encryption
*/
void esp_aes_encrypt( esp_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] )
{
esp_aes_acquire_hardware();
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
ets_aes_crypt(input, output);
esp_aes_release_hardware();
}
/*
* AES-ECB block decryption
*/
void esp_aes_decrypt( esp_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] )
{
esp_aes_acquire_hardware();
esp_aes_setkey_hardware(ctx, ESP_AES_DECRYPT);
ets_aes_crypt(input, output);
esp_aes_release_hardware();
}
/*
* AES-ECB block encryption/decryption
*/
int esp_aes_crypt_ecb( esp_aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16] )
{
esp_aes_acquire_hardware();
esp_aes_setkey_hardware(ctx, mode);
ets_aes_crypt(input, output);
esp_aes_release_hardware();
return 0;
}
/*
* AES-CBC buffer encryption/decryption
*/
int esp_aes_crypt_cbc( esp_aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output )
{
int i;
unsigned char temp[16];
if ( length % 16 ) {
return ( ERR_ESP_AES_INVALID_INPUT_LENGTH );
}
esp_aes_acquire_hardware();
esp_aes_setkey_hardware(ctx, mode);
if ( mode == ESP_AES_DECRYPT ) {
while ( length > 0 ) {
memcpy( temp, input, 16 );
ets_aes_crypt(input, output);
for ( i = 0; i < 16; i++ ) {
output[i] = (unsigned char)( output[i] ^ iv[i] );
}
memcpy( iv, temp, 16 );
input += 16;
output += 16;
length -= 16;
}
} else {
while ( length > 0 ) {
for ( i = 0; i < 16; i++ ) {
output[i] = (unsigned char)( input[i] ^ iv[i] );
}
ets_aes_crypt(output, output);
memcpy( iv, output, 16 );
input += 16;
output += 16;
length -= 16;
}
}
esp_aes_release_hardware();
return 0;
}
/*
* AES-CFB128 buffer encryption/decryption
*/
int esp_aes_crypt_cfb128( esp_aes_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output )
{
int c;
size_t n = *iv_off;
esp_aes_acquire_hardware();
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
if ( mode == ESP_AES_DECRYPT ) {
while ( length-- ) {
if ( n == 0 ) {
ets_aes_crypt(iv, iv );
}
c = *input++;
*output++ = (unsigned char)( c ^ iv[n] );
iv[n] = (unsigned char) c;
n = ( n + 1 ) & 0x0F;
}
} else {
while ( length-- ) {
if ( n == 0 ) {
ets_aes_crypt(iv, iv );
}
iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
n = ( n + 1 ) & 0x0F;
}
}
*iv_off = n;
esp_aes_release_hardware();
return 0;
}
/*
* AES-CFB8 buffer encryption/decryption
*/
int esp_aes_crypt_cfb8( esp_aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output )
{
unsigned char c;
unsigned char ov[17];
esp_aes_acquire_hardware();
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
while ( length-- ) {
memcpy( ov, iv, 16 );
ets_aes_crypt(iv, iv);
if ( mode == ESP_AES_DECRYPT ) {
ov[16] = *input;
}
c = *output++ = (unsigned char)( iv[0] ^ *input++ );
if ( mode == ESP_AES_ENCRYPT ) {
ov[16] = c;
}
memcpy( iv, ov + 1, 16 );
}
esp_aes_release_hardware();
return 0;
}
/*
* AES-CTR buffer encryption/decryption
*/
int esp_aes_crypt_ctr( esp_aes_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[16],
unsigned char stream_block[16],
const unsigned char *input,
unsigned char *output )
{
int c, i;
size_t n = *nc_off;
esp_aes_acquire_hardware();
esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT);
while ( length-- ) {
if ( n == 0 ) {
ets_aes_crypt(nonce_counter, stream_block);
for ( i = 16; i > 0; i-- )
if ( ++nonce_counter[i - 1] != 0 ) {
break;
}
}
c = *input++;
*output++ = (unsigned char)( c ^ stream_block[n] );
n = ( n + 1 ) & 0x0F;
}
*nc_off = n;
esp_aes_release_hardware();
return 0;
}

View file

@ -0,0 +1,267 @@
/*
* 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.
*
*/
/*
* The SHA-1 standard was published by NIST in 1993.
*
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
*/
#include <string.h>
#include <sys/lock.h>
#include "hwcrypto/sha.h"
#include "rom/ets_sys.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();
}
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);
}
/* 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)
{
/* Feed the SHA engine one block at a time */
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);
input += chunk_len;
ilen -= chunk_len;
}
}
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 );
}
////

View file

@ -0,0 +1,281 @@
/**
* \brief AES block cipher, ESP32 hardware accelerated version
* 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.
*
*
*/
#ifndef ESP_AES_H
#define ESP_AES_H
#include "esp_types.h"
#include "rom/aes.h"
#ifdef __cplusplus
extern "C" {
#endif
/* padlock.c and aesni.c rely on these values! */
#define ESP_AES_ENCRYPT 1
#define ESP_AES_DECRYPT 0
#define ERR_ESP_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
#define ERR_ESP_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
typedef struct {
enum AES_BITS aesbits;
uint8_t key[32];
} key_context, KEY_CTX;
/**
* \brief AES context structure
*
* \note buf is able to hold 32 extra bytes, which can be used:
* - for alignment purposes if VIA padlock is used, and/or
* - to simplify key expansion in the 256-bit case by
* generating an extra round key
*/
typedef struct {
int nr; /*!< number of rounds */
uint32_t *rk; /*!< AES round keys */
KEY_CTX enc;
KEY_CTX dec;
} esp_aes_context;
/**
* \brief Lock access to AES hardware unit
*
* AES hardware unit can only be used by one
* consumer at a time.
*
* esp_aes_xxx API calls automatically manage locking & unlocking of
* hardware, this function is only needed if you want to call
* ets_aes_xxx functions directly.
*/
void esp_aes_acquire_hardware( void );
/**
* \brief Unlock access to AES hardware unit
*
* esp_aes_xxx API calls automatically manage locking & unlocking of
* hardware, this function is only needed if you want to call
* ets_aes_xxx functions directly.
*/
void esp_aes_release_hardware( void );
/**
* \brief Initialize AES context
*
* \param ctx AES context to be initialized
*/
void esp_aes_init( esp_aes_context *ctx );
/**
* \brief Clear AES context
*
* \param ctx AES context to be cleared
*/
void esp_aes_free( esp_aes_context *ctx );
/**
* \brief AES key schedule (encryption)
*
* \param ctx AES context to be initialized
* \param key encryption key
* \param keybits must be 128, 192 or 256
*
* \return 0 if successful, or ERR_AES_INVALID_KEY_LENGTH
*/
int esp_aes_setkey_enc( esp_aes_context *ctx, const unsigned char *key, unsigned int keybits );
/**
* \brief AES key schedule (decryption)
*
* \param ctx AES context to be initialized
* \param key decryption key
* \param keybits must be 128, 192 or 256
*
* \return 0 if successful, or ERR_AES_INVALID_KEY_LENGTH
*/
int esp_aes_setkey_dec( esp_aes_context *ctx, const unsigned char *key, unsigned int keybits );
/**
* \brief AES-ECB block encryption/decryption
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param input 16-byte input block
* \param output 16-byte output block
*
* \return 0 if successful
*/
int esp_aes_crypt_ecb( esp_aes_context *ctx, int mode, const unsigned char input[16], unsigned char output[16] );
/**
* \brief AES-CBC buffer encryption/decryption
* Length should be a multiple of the block
* size (16 bytes)
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful, or ERR_AES_INVALID_INPUT_LENGTH
*/
int esp_aes_crypt_cbc( esp_aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief AES-CFB128 buffer encryption/decryption.
*
* Note: Due to the nature of CFB you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* esp_aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param length length of the input data
* \param iv_off offset in IV (updated after use)
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful
*/
int esp_aes_crypt_cfb128( esp_aes_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief AES-CFB8 buffer encryption/decryption.
*
* Note: Due to the nature of CFB you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* esp_aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
*
* \note Upon exit, the content of the IV is updated so that you can
* call the function same function again on the following
* block(s) of data and get the same result as if it was
* encrypted in one call. This allows a "streaming" usage.
* If on the other hand you need to retain the contents of the
* IV, you should either save it manually or use the cipher
* module instead.
*
* \param ctx AES context
* \param mode AES_ENCRYPT or AES_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*
* \return 0 if successful
*/
int esp_aes_crypt_cfb8( esp_aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief AES-CTR buffer encryption/decryption
*
* Warning: You have to keep the maximum use of your counter in mind!
*
* Note: Due to the nature of CTR you should use the same key schedule for
* both encryption and decryption. So a context initialized with
* esp_aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
*
* \param ctx AES context
* \param length The length of the data
* \param nc_off The offset in the current stream_block (for resuming
* within current cipher stream). The offset pointer to
* should be 0 at the start of a stream.
* \param nonce_counter The 128-bit nonce and counter.
* \param stream_block The saved stream-block for resuming. Is overwritten
* by the function.
* \param input The input data stream
* \param output The output data stream
*
* \return 0 if successful
*/
int esp_aes_crypt_ctr( esp_aes_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[16],
unsigned char stream_block[16],
const unsigned char *input,
unsigned char *output );
/**
* \brief Internal AES block encryption function
* (Only exposed to allow overriding it,
* see AES_ENCRYPT_ALT)
*
* \param ctx AES context
* \param input Plaintext block
* \param output Output (ciphertext) block
*/
void esp_aes_encrypt( esp_aes_context *ctx, const unsigned char input[16], unsigned char output[16] );
/**
* \brief Internal AES block decryption function
* (Only exposed to allow overriding it,
* see AES_DECRYPT_ALT)
*
* \param ctx AES context
* \param input Ciphertext block
* \param output Output (plaintext) block
*/
void esp_aes_decrypt( esp_aes_context *ctx, const unsigned char input[16], unsigned char output[16] );
#ifdef __cplusplus
}
#endif
#endif /* aes.h */

View file

@ -0,0 +1,250 @@
/*
* 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.
*
*/
#ifndef _ESP_SHA_H_
#define _ESP_SHA_H_
#include "rom/sha.h"
#include "esp_types.h"
#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;
/**
* \brief Lock access to SHA hardware unit
*
* SHA hardware unit can only be used by one
* consumer at a time.
*
* 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
*
* 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
*
* \param ctx SHA-1 context to be initialized
*/
void esp_sha1_init( esp_sha_context *ctx );
/**
* \brief Clear SHA-1 context
*
* \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 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 ctx context to be initialized
*/
void esp_sha1_start( esp_sha_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 esp_sha1_update( esp_sha_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 esp_sha1_finish( esp_sha_context *ctx, unsigned char output[20] );
/**
* \brief Calculate SHA-1 of input buffer
*
* \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 ctx SHA-256 context to be initialized
*/
void esp_sha256_init( esp_sha_context *ctx );
/**
* \brief Clear SHA-256 context
*
* \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 dst The destination context
* \param src The context to be cloned
*/
void esp_sha256_clone( esp_sha_context *dst, const esp_sha_context *src );
/**
* \brief SHA-256 context setup
*
* \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
*
* \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
*
* \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
*
* \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
*
* \param ctx SHA-512 context to be initialized
*/
void esp_sha512_init( esp_sha_context *ctx );
/**
* \brief Clear SHA-512 context
*
* \param ctx SHA-512 context to be cleared
*/
void esp_sha512_free( esp_sha_context *ctx );
/**
* \brief Clone (the state of) a SHA-512 context
*
* \param dst The destination context
* \param src The context to be cloned
*/
void esp_sha512_clone( esp_sha_context *dst, const esp_sha_context *src );
/**
* \brief SHA-512 context setup
*
* \param ctx context to be initialized
* \param is384 0 = use SHA512, 1 = use SHA384
*/
void esp_sha512_start( esp_sha_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 esp_sha512_update( esp_sha_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 esp_sha512_finish( esp_sha_context *ctx, unsigned char output[64] );
/**
* \brief Calculate SHA-512 of input buffer.
*
* \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
*/
void esp_sha512( const unsigned char *input, size_t ilen, unsigned char output[64], int is384 );
//
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,3 +1,10 @@
/*
ROM functions for hardware AES support.
It is not recommended to use these functions directly,
use the wrapper functions in hwcrypto/aes.h instead.
*/
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");

View file

@ -1,3 +1,10 @@
/*
ROM functions for hardware bigint support.
It is not recommended to use these functions directly,
use the wrapper functions in hwcrypto/mpi.h instead.
*/
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");

View file

@ -1,3 +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.
*/
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -30,7 +37,8 @@ enum SHA_TYPE {
SHA1 = 0,
SHA2_256,
SHA2_384,
SHA2_512
SHA2_512,
SHA_INVALID = -1,
};
void ets_sha_init(SHA_CTX *ctx);

View file

@ -10,6 +10,6 @@ COMPONENT_ADD_INCLUDEDIRS := port/include include/expat
COMPONENT_SRCDIRS := library port
EXTRA_CFLAGS := -Wno-error=address -Waddress -DHAVE_EXPAT_CONFIG_H
CFLAGS += -Wno-error=address -Waddress -DHAVE_EXPAT_CONFIG_H
include $(IDF_PATH)/make/component.mk
include $(IDF_PATH)/make/component_common.mk

View file

@ -10,4 +10,4 @@ COMPONENT_ADD_INCLUDEDIRS := include port/include
COMPONENT_SRCDIRS := library port
include $(IDF_PATH)/make/component.mk
include $(IDF_PATH)/make/component_common.mk

View file

@ -2,10 +2,10 @@
# Component Makefile
#
COMPONENT_ADD_INCLUDEDIRS := include/lwip include/lwip/port
COMPONENT_ADD_INCLUDEDIRS := include/lwip include/lwip/port include/lwip/posix
COMPONENT_SRCDIRS := api apps/sntp apps core/ipv4 core/ipv6 core netif port/freertos port/netif port
EXTRA_CFLAGS := -Wno-error=address -Waddress
CFLAGS += -Wno-error=address -Waddress
include $(IDF_PATH)/make/component_common.mk

View file

@ -1,8 +0,0 @@
#
# Component Makefile
COMPONENT_SRCDIRS := library port
EXTRA_CFLAGS += -DMBEDTLS_CONFIG_FILE='"mbedtls/esp_config.h"'
include $(IDF_PATH)/make/component.mk

View file

@ -0,0 +1,4 @@
# Anyone compiling mbedTLS code needs the name of the
# alternative config file
CFLAGS += -DMBEDTLS_CONFIG_FILE='"mbedtls/esp_config.h"'

View file

@ -0,0 +1,9 @@
#
# Component Makefile
#
COMPONENT_ADD_INCLUDEDIRS := port/include include
COMPONENT_SRCDIRS := library port
include $(IDF_PATH)/make/component_common.mk

View file

@ -100,6 +100,8 @@
#define MBEDTLS_LN_2_DIV_LN_10_SCALE100 332
#define MBEDTLS_MPI_RW_BUFFER_SIZE ( ((MBEDTLS_MPI_MAX_BITS_SCALE100 + MBEDTLS_LN_2_DIV_LN_10_SCALE100 - 1) / MBEDTLS_LN_2_DIV_LN_10_SCALE100) + 10 + 6 )
#if !defined(MBEDTLS_BIGNUM_ALT)
/*
* Define the base integer type, architecture-wise.
*
@ -702,6 +704,9 @@ int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
#else /* MBEDTLS_BIGNUM_ALT */
#include "bignum_alt.h"
#endif /* MBEDTLS_BIGNUM_ALT */
/**
* \brief Checkup routine

View file

@ -101,6 +101,9 @@ void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *in
*/
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] );
#ifdef __cplusplus
}
#endif
@ -131,9 +134,6 @@ void mbedtls_sha512( const unsigned char *input, size_t ilen,
*/
int mbedtls_sha512_self_test( int verbose );
/* Internal use */
void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] );
#ifdef __cplusplus
}
#endif

View file

@ -58,6 +58,8 @@
#define mbedtls_free free
#endif
#if !defined(MBEDTLS_BIGNUM_ALT)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n ) {
volatile mbedtls_mpi_uint *p = v; while( n-- ) *p++ = 0;
@ -1162,6 +1164,7 @@ void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mp
while( c != 0 );
}
#if !defined(MBEDTLS_MPI_MUL_MPI_ALT)
/*
* Baseline multiplication: X = A * B (HAC 14.12)
*/
@ -1198,6 +1201,7 @@ cleanup:
return( ret );
}
#endif
/*
* Baseline multiplication: X = A * b
@ -1596,6 +1600,7 @@ static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint m
return( mpi_montmul( A, &U, N, mm, T ) );
}
#if !defined(MBEDTLS_MPI_EXP_MOD_ALT)
/*
* Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
*/
@ -1803,6 +1808,7 @@ cleanup:
return( ret );
}
#endif
/*
* Greatest common divisor: G = gcd(A, B) (HAC 14.54)
@ -2264,6 +2270,7 @@ cleanup:
}
#endif /* MBEDTLS_GENPRIME */
#endif /* MBEDTLS_BIGNUM_ALT */
#if defined(MBEDTLS_SELF_TEST)

View file

@ -0,0 +1,536 @@
/**
* \brief Multi-precision integer library, ESP32 hardware accelerated parts
*
* based on mbedTLS implementation
*
* 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.
*
*/
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include "mbedtls/bignum.h"
#include "mbedtls/bn_mul.h"
#include "rom/bigint.h"
#if defined(MBEDTLS_MPI_MUL_MPI_ALT) || defined(MBEDTLS_MPI_EXP_MOD_ALT)
/* Constants from mbedTLS bignum.c */
#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
#define biL (ciL << 3) /* bits in limb */
static _lock_t mpi_lock;
/* At the moment these hardware locking functions aren't exposed publically
for MPI. If you want to use the ROM bigint functions and co-exist with mbedTLS,
please raise a feature request.
*/
static void esp_mpi_acquire_hardware( void )
{
/* newlib locks lazy initialize on ESP-IDF */
_lock_acquire(&mpi_lock);
ets_bigint_enable();
}
static void esp_mpi_release_hardware( void )
{
ets_bigint_disable();
_lock_release(&mpi_lock);
}
/*
* Helper for mbedtls_mpi multiplication
* copied/trimmed from mbedtls bignum.c
*/
static void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mpi_uint b )
{
mbedtls_mpi_uint c = 0, t = 0;
for( ; i >= 16; i -= 16 )
{
MULADDC_INIT
MULADDC_CORE MULADDC_CORE
MULADDC_CORE MULADDC_CORE
MULADDC_CORE MULADDC_CORE
MULADDC_CORE MULADDC_CORE
MULADDC_CORE MULADDC_CORE
MULADDC_CORE MULADDC_CORE
MULADDC_CORE MULADDC_CORE
MULADDC_CORE MULADDC_CORE
MULADDC_STOP
}
for( ; i >= 8; i -= 8 )
{
MULADDC_INIT
MULADDC_CORE MULADDC_CORE
MULADDC_CORE MULADDC_CORE
MULADDC_CORE MULADDC_CORE
MULADDC_CORE MULADDC_CORE
MULADDC_STOP
}
for( ; i > 0; i-- )
{
MULADDC_INIT
MULADDC_CORE
MULADDC_STOP
}
t++;
do {
*d += c; c = ( *d < c ); d++;
}
while( c != 0 );
}
/*
* Helper for mbedtls_mpi subtraction
* Copied/adapter from mbedTLS bignum.c
*/
static void mpi_sub_hlp( size_t n, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d )
{
size_t i;
mbedtls_mpi_uint c, z;
for( i = c = 0; i < n; i++, s++, d++ )
{
z = ( *d < c ); *d -= c;
c = ( *d < *s ) + z; *d -= *s;
}
while( c != 0 )
{
z = ( *d < c ); *d -= c;
c = z; i++; d++;
}
}
/* The following 3 Montgomery arithmetic function are
copied from mbedTLS bigint.c verbatim as they are static.
TODO: find a way to support making the versions in mbedtls
non-static.
*/
/*
* Fast Montgomery initialization (thanks to Tom St Denis)
*/
static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
{
mbedtls_mpi_uint x, m0 = N->p[0];
unsigned int i;
x = m0;
x += ( ( m0 + 2 ) & 4 ) << 1;
for( i = biL; i >= 8; i /= 2 )
x *= ( 2 - ( m0 * x ) );
*mm = ~x + 1;
}
/*
* Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
*/
static int mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
const mbedtls_mpi *T )
{
size_t i, n, m;
mbedtls_mpi_uint u0, u1, *d;
if( T->n < N->n + 1 || T->p == NULL )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
memset( T->p, 0, T->n * ciL );
d = T->p;
n = N->n;
m = ( B->n < n ) ? B->n : n;
for( i = 0; i < n; i++ )
{
/*
* T = (T + u0*B + u1*N) / 2^biL
*/
u0 = A->p[i];
u1 = ( d[0] + u0 * B->p[0] ) * mm;
mpi_mul_hlp( m, B->p, d, u0 );
mpi_mul_hlp( n, N->p, d, u1 );
*d++ = u0; d[n + 1] = 0;
}
memcpy( A->p, d, ( n + 1 ) * ciL );
if( mbedtls_mpi_cmp_abs( A, N ) >= 0 )
mpi_sub_hlp( n, N->p, A->p );
else
/* prevent timing attacks */
mpi_sub_hlp( n, A->p, T->p );
return( 0 );
}
/*
* Montgomery reduction: A = A * R^-1 mod N
*/
static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T )
{
mbedtls_mpi_uint z = 1;
mbedtls_mpi U;
U.n = U.s = (int) z;
U.p = &z;
return( mpi_montmul( A, &U, N, mm, T ) );
}
/* Allocate parameters used by hardware MPI multiply,
and copy mbedtls_mpi structures into them */
static int mul_pram_alloc(const mbedtls_mpi *A, const mbedtls_mpi *B, char **pA, char **pB, char **pX, size_t *bites)
{
char *sa, *sb, *sx;
// int algn;
int words, bytes;
int abytes, bbytes;
if (A->n > B->n)
words = A->n;
else
words = B->n;
bytes = (words / 16 + ((words % 16) ? 1 : 0 )) * 16 * 4 * 2;
abytes = A->n * 4;
bbytes = B->n * 4;
sa = malloc(bytes);
if (!sa) {
return -1;
}
sb = malloc(bytes);
if (!sb) {
free(sa);
return -1;
}
sx = malloc(bytes);
if (!sx) {
free(sa);
free(sb);
return -1;
}
memcpy(sa, A->p, abytes);
memset(sa + abytes, 0, bytes - abytes);
memcpy(sb, B->p, bbytes);
memset(sb + bbytes, 0, bytes - bbytes);
*pA = sa;
*pB = sb;
*pX = sx;
*bites = bytes * 4;
return 0;
}
#if defined(MBEDTLS_MPI_MUL_MPI_ALT)
int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
int ret = -1;
size_t i, j;
char *s1 = NULL, *s2 = NULL, *dest = NULL;
size_t bites;
mbedtls_mpi TA, TB;
mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
if( X == A ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); A = &TA; }
if( X == B ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); B = &TB; }
for( i = A->n; i > 0; i-- )
if( A->p[i - 1] != 0 )
break;
for( j = B->n; j > 0; j-- )
if( B->p[j - 1] != 0 )
break;
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
if (mul_pram_alloc(A, B, &s1, &s2, &dest, &bites)) {
goto cleanup;
}
esp_mpi_acquire_hardware();
if (ets_bigint_mult_prepare((uint32_t *)s1, (uint32_t *)s2, bites)){
ets_bigint_wait_finish();
if (ets_bigint_mult_getz((uint32_t *)dest, bites) == true) {
memcpy(X->p, dest, (i + j) * 4);
ret = 0;
} else {
printf("ets_bigint_mult_getz failed\n");
}
} else{
printf("Baseline multiplication failed\n");
}
esp_mpi_release_hardware();
X->s = A->s * B->s;
free(s1);
free(s2);
free(dest);
cleanup:
mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TA );
return( ret );
}
#endif /* MBEDTLS_MPI_MUL_MPI_ALT */
#if defined(MBEDTLS_MPI_EXP_MOD_ALT)
/*
* Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
*/
int mbedtls_mpi_exp_mod( mbedtls_mpi* X, const mbedtls_mpi* A, const mbedtls_mpi* E, const mbedtls_mpi* N, mbedtls_mpi* _RR )
{
int ret;
size_t wbits, wsize, one = 1;
size_t i, j, nblimbs;
size_t bufsize, nbits;
mbedtls_mpi_uint ei, mm, state;
mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
int neg;
if( mbedtls_mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
/*
* Init temps and window size
*/
mpi_montg_init( &mm, N );
mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T );
mbedtls_mpi_init( &Apos );
memset( W, 0, sizeof( W ) );
i = mbedtls_mpi_bitlen( E );
wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
if( wsize > MBEDTLS_MPI_WINDOW_SIZE )
wsize = MBEDTLS_MPI_WINDOW_SIZE;
j = N->n + 1;
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], j ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) );
/*
* Compensate for negative A (and correct at the end)
*/
neg = ( A->s == -1 );
if( neg )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Apos, A ) );
Apos.s = 1;
A = &Apos;
}
/*
* If 1st call, pre-compute R^2 mod N
*/
if( _RR == NULL || _RR->p == NULL )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &RR, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &RR, N->n * 2 * biL ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &RR, &RR, N ) );
if( _RR != NULL )
memcpy( _RR, &RR, sizeof( mbedtls_mpi) );
}
else
memcpy( &RR, _RR, sizeof( mbedtls_mpi) );
/*
* W[1] = A * R^2 * R^-1 mod N = A * R mod N
*/
if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 )
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) );
else
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
mpi_montmul( &W[1], &RR, N, mm, &T );
/*
* X = R^2 * R^-1 mod N = R mod N
*/
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) );
mpi_montred( X, N, mm, &T );
if( wsize > 1 )
{
/*
* W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
*/
j = one << ( wsize - 1 );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[j], N->n + 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) );
for( i = 0; i < wsize - 1; i++ )
mpi_montmul( &W[j], &W[j], N, mm, &T );
/*
* W[i] = W[i - 1] * W[1]
*/
for( i = j + 1; i < ( one << wsize ); i++ )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) );
mpi_montmul( &W[i], &W[1], N, mm, &T );
}
}
nblimbs = E->n;
bufsize = 0;
nbits = 0;
wbits = 0;
state = 0;
while( 1 )
{
if( bufsize == 0 )
{
if( nblimbs == 0 )
break;
nblimbs--;
bufsize = sizeof( mbedtls_mpi_uint ) << 3;
}
bufsize--;
ei = (E->p[nblimbs] >> bufsize) & 1;
/*
* skip leading 0s
*/
if( ei == 0 && state == 0 )
continue;
if( ei == 0 && state == 1 )
{
/*
* out of window, square X
*/
mpi_montmul( X, X, N, mm, &T );
continue;
}
/*
* add ei to current window
*/
state = 2;
nbits++;
wbits |= ( ei << ( wsize - nbits ) );
if( nbits == wsize )
{
/*
* X = X^wsize R^-1 mod N
*/
for( i = 0; i < wsize; i++ )
mpi_montmul( X, X, N, mm, &T );
/*
* X = X * W[wbits] R^-1 mod N
*/
mpi_montmul( X, &W[wbits], N, mm, &T );
state--;
nbits = 0;
wbits = 0;
}
}
/*
* process the remaining bits
*/
for( i = 0; i < nbits; i++ )
{
mpi_montmul( X, X, N, mm, &T );
wbits <<= 1;
if( ( wbits & ( one << wsize ) ) != 0 )
mpi_montmul( X, &W[1], N, mm, &T );
}
/*
* X = A^E * R * R^-1 mod N = A^E mod N
*/
mpi_montred( X, N, mm, &T );
if( neg )
{
X->s = -1;
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) );
}
cleanup:
for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ )
mbedtls_mpi_free( &W[i] );
mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos );
if( _RR == NULL || _RR->p == NULL )
mbedtls_mpi_free( &RR );
return( ret );
}
#endif /* MBEDTLS_MPI_EXP_MOD_ALT */
#endif /* MBEDTLS_MPI_MUL_MPI_ALT || MBEDTLS_MPI_EXP_MOD_ALT */

View file

@ -0,0 +1,23 @@
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
extern int os_get_random(unsigned char *buf, size_t len);
int mbedtls_hardware_poll( void *data,
unsigned char *output, size_t len, size_t *olen )
{
os_get_random(output, len);
*olen = len;
return 0;
}
#endif

View file

@ -0,0 +1,59 @@
/**
* \file aes_alt.h
*
* \brief AES block cipher
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
*/
#ifndef AES_ALT_H
#define AES_ALT_H
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_AES_ALT)
#include "hwcrypto/aes.h"
typedef esp_aes_context mbedtls_aes_context;
#define mbedtls_aes_init esp_aes_init
#define mbedtls_aes_free esp_aes_free
#define mbedtls_aes_setkey_enc esp_aes_setkey_enc
#define mbedtls_aes_setkey_dec esp_aes_setkey_dec
#define mbedtls_aes_crypt_ecb esp_aes_crypt_ecb
#if defined(MBEDTLS_CIPHER_MODE_CBC)
#define mbedtls_aes_crypt_cbc esp_aes_crypt_cbc
#endif
#if defined(MBEDTLS_CIPHER_MODE_CFB)
#define mbedtls_aes_crypt_cfb128 esp_aes_crypt_cfb128
#define mbedtls_aes_crypt_cfb8 esp_aes_crypt_cfb8
#endif
#if defined(MBEDTLS_CIPHER_MODE_CTR)
#define mbedtls_aes_crypt_ctr esp_aes_crypt_ctr
#endif
#define mbedtls_aes_encrypt esp_aes_encrypt
#define mbedtls_aes_decrypt esp_aes_decrypt
#endif /* MBEDTLS_AES_ALT */
#ifdef __cplusplus
}
#endif
#endif /* aes.h */

View file

@ -1,7 +1,6 @@
/**
* \file config.h
*
* \brief Configuration options (set of defines)
* \brief Default mbedTLS configuration options for esp-idf
*
* This set of compile-time options may be used to enable
* or disable features selectively, and reduce the global
@ -225,7 +224,6 @@
* Uncomment a macro to enable alternate implementation of the corresponding
* module.
*/
//#define MBEDTLS_AES_ALT
//#define MBEDTLS_ARC4_ALT
//#define MBEDTLS_BLOWFISH_ALT
//#define MBEDTLS_CAMELLIA_ALT
@ -235,10 +233,27 @@
//#define MBEDTLS_MD4_ALT
//#define MBEDTLS_MD5_ALT
//#define MBEDTLS_RIPEMD160_ALT
/* The following units have ESP32 hardware support,
uncommenting each _ALT macro will use the
hardware-accelerated implementation. */
#define MBEDTLS_AES_ALT
/* 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
/* The following MPI (bignum) functions have ESP32 hardware support,
Uncommenting these macros will use the hardware-accelerated
implementations.
Disabled as number of limbs limited by bug. Internal TW#7112.
*/
//#define MBEDTLS_MPI_EXP_MOD_ALT
//#define MBEDTLS_MPI_MUL_MPI_ALT
/**
* \def MBEDTLS_MD2_PROCESS_ALT
*
@ -297,7 +312,7 @@
*
* Uncomment this macro to store the AES tables in ROM.
*/
//#define MBEDTLS_AES_ROM_TABLES
#define MBEDTLS_AES_ROM_TABLES
/**
* \def MBEDTLS_CAMELLIA_SMALL_MEMORY
@ -2465,7 +2480,8 @@
//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */
/* SSL options */
//#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */
#define MBEDTLS_SSL_MAX_CONTENT_LEN 5120 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */
//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */
//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
@ -2506,6 +2522,6 @@
#include MBEDTLS_USER_CONFIG_FILE
#endif
#include "check_config.h"
#include "mbedtls/check_config.h"
#endif /* MBEDTLS_CONFIG_H */

View file

@ -0,0 +1,33 @@
/*
* copyright (c) 2010 - 2012 Espressif System
*
*/
#ifndef _SHA1_ALT_H_
#define _SHA1_ALT_H_
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_SHA1_ALT)
#include "hwcrypto/sha.h"
typedef esp_sha_context 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(...)
#endif
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,33 @@
/*
* copyright (c) 2010 - 2012 Espressif System
*
*/
#ifndef _SHA256_ALT_H_
#define _SHA256_ALT_H_
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_SHA256_ALT)
#include "hwcrypto/sha.h"
typedef esp_sha_context 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(...)
#endif
#ifdef __cplusplus
}
#endif
#endif /* sha256.h */

View file

@ -0,0 +1,33 @@
/*
* copyright (c) 2010 - 2012 Espressif System
*
* esf Link List Descriptor
*/
#ifndef _SHA512_ALT_H_
#define _SHA512_ALT_H_
#ifdef __cplusplus
extern "C" {
#endif
#if defined(MBEDTLS_SHA512_ALT)
#include "hwcrypto/sha.h"
typedef esp_sha_context mbedtls_sha512_context;
#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(...)
#endif
#ifdef __cplusplus
}
#endif
#endif /* sha512.h */

View file

@ -0,0 +1,452 @@
/*
* TCP/IP or UDP/IP networking functions
* modified for LWIP support on ESP32
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* Additions Copyright (C) 2015 Angus Gratton
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if !defined(MBEDTLS_NET_C)
#include "mbedtls/net.h"
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <stdint.h>
/*
* Prepare for using the sockets interface
*/
static int net_prepare( void )
{
return ( 0 );
}
static int mbedtls_net_errno(int fd)
{
int sock_errno = 0;
u32_t optlen = sizeof(sock_errno);
getsockopt(fd, SOL_SOCKET, SO_ERROR, &sock_errno, &optlen);
return sock_errno;
}
/*
* Initialize a context
*/
void mbedtls_net_init( mbedtls_net_context *ctx )
{
ctx->fd = -1;
}
/*
* Initiate a TCP connection with host:port and the given protocol
*/
int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto )
{
int ret;
struct addrinfo hints, *addr_list, *cur;
if ( ( ret = net_prepare() ) != 0 ) {
return ( ret );
}
/* Do name resolution with both IPv6 and IPv4 */
memset( &hints, 0, sizeof( hints ) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
if ( getaddrinfo( host, port, &hints, &addr_list ) != 0 ) {
return ( MBEDTLS_ERR_NET_UNKNOWN_HOST );
}
/* Try the sockaddrs until a connection succeeds */
ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
for ( cur = addr_list; cur != NULL; cur = cur->ai_next ) {
ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
cur->ai_protocol );
if ( ctx->fd < 0 ) {
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
continue;
}
if ( connect( ctx->fd, cur->ai_addr, cur->ai_addrlen ) == 0 ) {
ret = 0;
break;
}
close( ctx->fd );
ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
}
freeaddrinfo( addr_list );
return ( ret );
}
/*
* Create a listening socket on bind_ip:port
*/
int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto )
{
int ret;
struct addrinfo hints, *addr_list, *cur;
if ( ( ret = net_prepare() ) != 0 ) {
return ( ret );
}
/* Bind to IPv6 and/or IPv4, but only in the desired protocol */
memset( &hints, 0, sizeof( hints ) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
if ( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 ) {
return ( MBEDTLS_ERR_NET_UNKNOWN_HOST );
}
/* Try the sockaddrs until a binding succeeds */
ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
for ( cur = addr_list; cur != NULL; cur = cur->ai_next ) {
ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
cur->ai_protocol );
if ( ctx->fd < 0 ) {
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
continue;
}
/*SO_REUSEADDR option dafault is disable in source code(lwip)*/
#if SO_REUSE
n = 1;
if ( setsockopt( ctx->fd, SOL_SOCKET, SO_REUSEADDR,
(const char *) &n, sizeof( n ) ) != 0 ) {
close( ctx->fd );
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
continue;
}
#endif
/*bind interface dafault don't process the addr is 0xffffffff for TCP Protocol*/
struct sockaddr_in *serv_addr = NULL;
serv_addr = (struct sockaddr_in *)cur->ai_addr;
serv_addr->sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
if ( bind( ctx->fd, (struct sockaddr *)serv_addr, cur->ai_addrlen ) != 0 ) {
close( ctx->fd );
ret = MBEDTLS_ERR_NET_BIND_FAILED;
continue;
}
/* Listen only makes sense for TCP */
if ( proto == MBEDTLS_NET_PROTO_TCP ) {
if ( listen( ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 ) {
close( ctx->fd );
ret = MBEDTLS_ERR_NET_LISTEN_FAILED;
continue;
}
}
/* I we ever get there, it's a success */
ret = 0;
break;
}
freeaddrinfo( addr_list );
return ( ret );
}
/*
* Check if the requested operation would be blocking on a non-blocking socket
* and thus 'failed' with a negative return value.
*
* Note: on a blocking socket this function always returns 0!
*/
static int net_would_block( const mbedtls_net_context *ctx )
{
/*
* Never return 'WOULD BLOCK' on a non-blocking socket
*/
if ( ( fcntl( ctx->fd, F_GETFL, 0) & O_NONBLOCK ) != O_NONBLOCK ) {
return ( 0 );
}
int error = mbedtls_net_errno(ctx->fd);
switch ( error ) {
#if defined EAGAIN
case EAGAIN:
#endif
#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif
return ( 1 );
}
return ( 0 );
}
/*
* Accept a connection from a remote client
*/
int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
mbedtls_net_context *client_ctx,
void *client_ip, size_t buf_size, size_t *ip_len )
{
int ret;
int type;
struct sockaddr_in client_addr;
socklen_t n = (socklen_t) sizeof( client_addr );
socklen_t type_len = (socklen_t) sizeof( type );
/* Is this a TCP or UDP socket? */
if ( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE,
(void *) &type, (socklen_t *) &type_len ) != 0 ||
( type != SOCK_STREAM && type != SOCK_DGRAM ) ) {
return ( MBEDTLS_ERR_NET_ACCEPT_FAILED );
}
if ( type == SOCK_STREAM ) {
/* TCP: actual accept() */
ret = client_ctx->fd = (int) accept( bind_ctx->fd,
(struct sockaddr *) &client_addr, &n );
} else {
/* UDP: wait for a message, but keep it in the queue */
char buf[1] = { 0 };
ret = recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK,
(struct sockaddr *) &client_addr, &n );
}
if ( ret < 0 ) {
if ( net_would_block( bind_ctx ) != 0 ) {
return ( MBEDTLS_ERR_SSL_WANT_READ );
}
return ( MBEDTLS_ERR_NET_ACCEPT_FAILED );
}
/* UDP: hijack the listening socket to communicate with the client,
* then bind a new socket to accept new connections */
if ( type != SOCK_STREAM ) {
struct sockaddr_in local_addr;
int one = 1;
if ( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 ) {
return ( MBEDTLS_ERR_NET_ACCEPT_FAILED );
}
client_ctx->fd = bind_ctx->fd;
bind_ctx->fd = -1; /* In case we exit early */
n = sizeof( struct sockaddr_in );
if ( getsockname( client_ctx->fd,
(struct sockaddr *) &local_addr, &n ) != 0 ||
( bind_ctx->fd = (int) socket( AF_INET,
SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
(const char *) &one, sizeof( one ) ) != 0 ) {
return ( MBEDTLS_ERR_NET_SOCKET_FAILED );
}
if ( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 ) {
return ( MBEDTLS_ERR_NET_BIND_FAILED );
}
}
if ( client_ip != NULL ) {
struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
*ip_len = sizeof( addr4->sin_addr.s_addr );
if ( buf_size < *ip_len ) {
return ( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
}
memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len );
}
return ( 0 );
}
/*
* Set the socket blocking or non-blocking
*/
int mbedtls_net_set_block( mbedtls_net_context *ctx )
{
return ( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL, 0 ) & ~O_NONBLOCK ) );
}
int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
{
return ( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL, 0 ) | O_NONBLOCK ) );
}
/*
* Portable usleep helper
*/
void mbedtls_net_usleep( unsigned long usec )
{
struct timeval tv;
tv.tv_sec = usec / 1000000;
tv.tv_usec = usec % 1000000;
select( 0, NULL, NULL, NULL, &tv );
}
/*
* Read at most 'len' characters
*/
int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
{
int ret;
int fd = ((mbedtls_net_context *) ctx)->fd;
int error = 0;
if ( fd < 0 ) {
return ( MBEDTLS_ERR_NET_INVALID_CONTEXT );
}
ret = (int) read( fd, buf, len );
if ( ret < 0 ) {
if ( net_would_block( ctx ) != 0 ) {
return ( MBEDTLS_ERR_SSL_WANT_READ );
}
error = mbedtls_net_errno(fd);
if ( error == EPIPE || error == ECONNRESET ) {
return ( MBEDTLS_ERR_NET_CONN_RESET );
}
if ( error == EINTR ) {
return ( MBEDTLS_ERR_SSL_WANT_READ );
}
return ( MBEDTLS_ERR_NET_RECV_FAILED );
}
return ( ret );
}
/*
* Read at most 'len' characters, blocking for at most 'timeout' ms
*/
int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
uint32_t timeout )
{
int ret;
struct timeval tv;
fd_set read_fds;
int fd = ((mbedtls_net_context *) ctx)->fd;
if ( fd < 0 ) {
return ( MBEDTLS_ERR_NET_INVALID_CONTEXT );
}
FD_ZERO( &read_fds );
FD_SET( fd, &read_fds );
tv.tv_sec = timeout / 1000;
tv.tv_usec = ( timeout % 1000 ) * 1000;
ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv );
/* Zero fds ready means we timed out */
if ( ret == 0 ) {
return ( MBEDTLS_ERR_SSL_TIMEOUT );
}
if ( ret < 0 ) {
if ( errno == EINTR ) {
return ( MBEDTLS_ERR_SSL_WANT_READ );
}
return ( MBEDTLS_ERR_NET_RECV_FAILED );
}
/* This call will not block */
return ( mbedtls_net_recv( ctx, buf, len ) );
}
/*
* Write at most 'len' characters
*/
int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
{
int ret;
int fd = ((mbedtls_net_context *) ctx)->fd;
int error = 0;
if ( fd < 0 ) {
return ( MBEDTLS_ERR_NET_INVALID_CONTEXT );
}
ret = (int) write( fd, buf, len );
if ( ret < 0 ) {
if ( net_would_block( ctx ) != 0 ) {
return ( MBEDTLS_ERR_SSL_WANT_WRITE );
}
error = mbedtls_net_errno(fd);
if ( error == EPIPE || error == ECONNRESET ) {
return ( MBEDTLS_ERR_NET_CONN_RESET );
}
if ( error == EINTR ) {
return ( MBEDTLS_ERR_SSL_WANT_WRITE );
}
return ( MBEDTLS_ERR_NET_SEND_FAILED );
}
return ( ret );
}
/*
* Gracefully close the connection
*/
void mbedtls_net_free( mbedtls_net_context *ctx )
{
if ( ctx->fd == -1 ) {
return;
}
shutdown( ctx->fd, 2 );
close( ctx->fd );
ctx->fd = -1;
}
#endif /* MBEDTLS_NET_C */

View file

@ -60,7 +60,7 @@ influencing the build process of the component as well as the project it's used
in. Components may also include a Kconfig file defining the compile-time options that are
settable by means of the menu system.
Project makefile variables that can be set by the programmer::
Project Makefile variables that can be set by the programmer::
PROJECT_NAME: Mandatory. Name for the project
BUILD_DIR_BASE: Set the directory where all objects/libraries/binaries end up in.
@ -76,17 +76,20 @@ Project makefile variables that can be set by the programmer::
include directories that are passed to the compilation pass of all components and
they do not have a Kconfig option.
Component makefile variables that can be set by the programmer::
Component-specific component.mk variables that can be set by the programmer::
COMPONENT_ADD_INCLUDEDIRS: Relative path to include directories to be added to
the entire project
the entire project. If an include directory is only needed to compile this
specific component, don't add it here.
COMPONENT_PRIV_INCLUDEDIRS: Relative path to include directories that are only used
when compiling this specific component
when compiling this specific component.
COMPONENT_DEPENDS: Names of any components that need to be compiled before this component.
COMPONENT_ADD_LDFLAGS: Ld flags to add for this project. Defaults to -l$(COMPONENT_NAME).
COMPONENT_ADD_LDFLAGS: LD flags to add for the entire project. Defaults to -l$(COMPONENT_NAME).
Add libraries etc in the current directory as $(abspath libwhatever.a)
COMPONENT_EXTRA_INCLUDES: Any extra include paths. These will be prefixed with '-I' and
passed to the compiler; please put absolute paths here.
COMPONENT_EXTRA_INCLUDES: Any extra include paths used when compiling the component's
source files. These will be prefixed with '-I' and passed to the compiler.
Similar to COMPONENT_PRIV_INCLUDEDIRS, but these paths are passed as-is instead of
expanded relative to the component directory.
COMPONENT_SRCDIRS: Relative directories to look in for sources. Defaults to '.', the current
directory (the root of the component) only. Use this to specify any subdirectories. Note
that specifying this overwrites the default action of compiling everything in the
@ -114,6 +117,10 @@ be usable in component or project Makefiles::
COMPONENTS: Name of the components to be included
CONFIG_*: All values set by 'make menuconfig' have corresponding Makefile variables.
Inside your component's component.mk makefile, you can override or add to these variables
as necessary. The changes are isolated from other components (see Makefile.projbuild below
if you want to share these changes with all other components.)
For components, there also are these defines::
COMPONENT_PATH: Absolute path to the root of the source tree of the component we're
@ -152,10 +159,16 @@ details to add to "menuconfig" for this component.
Makefile.projbuild
------------------
For components that have parts that need to be run when building of the
project is done, you can create a file called Makefile.projbuild in the
component root directory. This file will be included in the main
Makefile.
For components that have parts that need to be evaluated in the top-level
project context, you can create a file called Makefile.projbuild in the
component root directory. These files is included into the project's
top-level Makefile.
For example, if your component needs to add to CFLAGS for the entire
project (not just for its own source files) then you can set
``CFLAGS +=`` in Makefile.projbuild. Note that this isn't necessary for
adding include directories to the project, you can set
``COMPONENT_ADD_INCLUDEDIRS`` (see above) in the component.mk.
KConfig.projbuild

View file

@ -8,32 +8,6 @@
# see project_config.mk for details.)
-include $(PROJECT_PATH)/build/include/config/auto.conf
ifeq ("$(LDFLAGS)","")
LDFLAGS = -nostdlib \
-L$(IDF_PATH)/lib \
-L$(IDF_PATH)/ld \
$(addprefix -L$(BUILD_DIR_BASE)/,$(COMPONENTS) $(SRCDIRS)) \
-u call_user_start_cpu0 \
-Wl,--gc-sections \
-Wl,-static \
-Wl,--start-group \
$(COMPONENT_LDFLAGS) \
-lgcc \
-Wl,--end-group
endif
ifeq ("$(CFLAGS)","")
CFLAGS = -DESP_PLATFORM -Og -std=gnu99 -g3 \
-Wpointer-arith -Werror -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable \
-Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -Wall -ffunction-sections -fdata-sections $(EXTRA_CFLAGS)
endif
ifeq ("$(CXXFLAGS)","")
CXXFLAGS = -DESP_PLATFORM -Og -std=gnu++11 -g3 \
-Wpointer-arith -Werror -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable \
-Wl,-EL -nostdlib -mlongcalls -Wall -ffunction-sections -fdata-sections $(EXTRA_CFLAGS) -fno-exceptions
endif
#Handling of V=1/VERBOSE=1 flag
#
# if V=1, $(summary) does nothing and $(details) will echo extra details

View file

@ -25,7 +25,7 @@ export COMPONENT_PATH
include $(IDF_PATH)/make/common.mk
#Some of these options are overridable by the components Makefile.
#Some of these options are overridable by the component's component.mk Makefile
#Name of the component
COMPONENT_NAME ?= $(lastword $(subst /, ,$(realpath $(COMPONENT_PATH))))
@ -58,7 +58,8 @@ COMPONENT_ADD_LDFLAGS ?= -l$(COMPONENT_NAME)
OWN_INCLUDES:=$(abspath $(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS) $(COMPONENT_PRIV_INCLUDEDIRS)))
COMPONENT_INCLUDES := $(OWN_INCLUDES) $(filter-out $(OWN_INCLUDES),$(COMPONENT_INCLUDES))
#This target is used to collect variable values from inside the main makefile
#This target is used to collect variable values from inside project.mk
# see project.mk GetVariable macro for details.
get_variable:
@echo "$(GET_VARIABLE)=$(call $(GET_VARIABLE)) "
@ -82,9 +83,6 @@ clean:
$(Q) rm -f $(COMPONENT_LIBRARY) $(COMPONENT_OBJS) $(COMPONENT_OBJS:.o=.d) $(COMPONENT_EXTRA_CLEAN)
endif
#Also generate dependency files
CFLAGS+=-MMD -MP
CXXFLAGS+=-MMD -MP
#Include all dependency files already generated
-include $(COMPONENT_OBJS:.o=.d)

View file

@ -133,6 +133,41 @@ export PROJECT_PATH
#Include functionality common to both project & component
-include $(IDF_PATH)/make/common.mk
# Set default LDFLAGS
LDFLAGS ?= -nostdlib \
-L$(IDF_PATH)/lib \
-L$(IDF_PATH)/ld \
$(addprefix -L$(BUILD_DIR_BASE)/,$(COMPONENTS) $(SRCDIRS)) \
-u call_user_start_cpu0 \
-Wl,--gc-sections \
-Wl,-static \
-Wl,--start-group \
$(COMPONENT_LDFLAGS) \
-lgcc \
-Wl,--end-group \
-Wl,-EL
# Set default CPPFLAGS, CFLAGS, CXXFLAGS
#
# These are exported so that components can use them when compiling.
#
# If you need your component to add CFLAGS/etc for it's own source compilation only, set CFLAGS += in your component's Makefile.
#
# If you need your component to add CFLAGS/etc globally for all source
# files, set CFLAGS += in your component's Makefile.projbuild
# CPPFLAGS used by an compile pass that uses the C preprocessor
CPPFLAGS = -DESP_PLATFORM -Og -g3 -Wpointer-arith -Werror -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable -Wall -ffunction-sections -fdata-sections -mlongcalls -nostdlib -MMD -MP
# C flags use by C only
CFLAGS = $(CPPFLAGS) -std=gnu99 -g3 -fno-inline-functions
# CXXFLAGS uses by C++ only
CXXFLAGS = $(CPPFLAGS) -Og -std=gnu++11 -g3 -fno-exceptions
export CFLAGS CPPFLAGS CXXFLAGS
#Set host compiler and binutils
HOSTCC := $(CC)
HOSTLD := $(LD)
@ -158,6 +193,7 @@ APP_BIN:=$(APP_ELF:.elf=.bin)
# Include any Makefile.projbuild file letting components add
# configuration at the project level
define includeProjBuildMakefile
$(if $(V),$(if $(wildcard $(1)/Makefile.projbuild),$(info including $(1)/Makefile.projbuild...)))
COMPONENT_PATH := $(1)
-include $(1)/Makefile.projbuild
endef

View file

@ -10,8 +10,6 @@ KCONFIG_TOOL_DIR=$(IDF_PATH)/tools/kconfig
# clear MAKEFLAGS as the menuconfig makefile uses implicit compile rules
$(KCONFIG_TOOL_DIR)/mconf $(KCONFIG_TOOL_DIR)/conf:
MAKEFLAGS="" \
CFLAGS="" \
LDFLAGS="" \
CC=$(HOSTCC) LD=$(HOSTLD) \
$(MAKE) -C $(KCONFIG_TOOL_DIR)

View file

@ -18,6 +18,10 @@ endif
# We need this, in case the user has it in its environment
unexport CONFIG_
# Unset some environment variables set in the project environment
CFLAGS :=
CPPFLAGS :=
LDFLAGS :=
default: mconf conf