Skip to content

Commit

Permalink
Merge branch 'bugfix/ble_mesh_split_tinycrypt_v4.2' into 'release/v4.2'
Browse files Browse the repository at this point in the history
Bugfix/ble mesh split tinycrypt (v4.2)

See merge request espressif/esp-idf!9371
  • Loading branch information
Isl2017 committed Jul 2, 2020
2 parents de5d145 + 76baeba commit f9cee60
Show file tree
Hide file tree
Showing 37 changed files with 5,714 additions and 286 deletions.
17 changes: 16 additions & 1 deletion components/bt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ if(CONFIG_BT_ENABLED)
if(CONFIG_BLE_MESH)
list(APPEND include_dirs
"esp_ble_mesh/mesh_common/include"
"esp_ble_mesh/mesh_common/tinycrypt/include"
"esp_ble_mesh/mesh_core"
"esp_ble_mesh/mesh_core/include"
"esp_ble_mesh/mesh_core/storage"
Expand Down Expand Up @@ -346,7 +347,21 @@ if(CONFIG_BT_ENABLED)
"esp_ble_mesh/btc/btc_ble_mesh_prov.c"
"esp_ble_mesh/btc/btc_ble_mesh_sensor_model.c"
"esp_ble_mesh/btc/btc_ble_mesh_time_scene_model.c"
"esp_ble_mesh/mesh_common/mesh_aes_encrypt.c"
"esp_ble_mesh/mesh_common/tinycrypt/src/aes_decrypt.c"
"esp_ble_mesh/mesh_common/tinycrypt/src/aes_encrypt.c"
"esp_ble_mesh/mesh_common/tinycrypt/src/cbc_mode.c"
"esp_ble_mesh/mesh_common/tinycrypt/src/ccm_mode.c"
"esp_ble_mesh/mesh_common/tinycrypt/src/cmac_mode.c"
"esp_ble_mesh/mesh_common/tinycrypt/src/ctr_mode.c"
"esp_ble_mesh/mesh_common/tinycrypt/src/ctr_prng.c"
"esp_ble_mesh/mesh_common/tinycrypt/src/ecc_dh.c"
"esp_ble_mesh/mesh_common/tinycrypt/src/ecc_dsa.c"
"esp_ble_mesh/mesh_common/tinycrypt/src/ecc_platform_specific.c"
"esp_ble_mesh/mesh_common/tinycrypt/src/ecc.c"
"esp_ble_mesh/mesh_common/tinycrypt/src/hmac_prng.c"
"esp_ble_mesh/mesh_common/tinycrypt/src/hmac.c"
"esp_ble_mesh/mesh_common/tinycrypt/src/sha256.c"
"esp_ble_mesh/mesh_common/tinycrypt/src/utils.c"
"esp_ble_mesh/mesh_common/mesh_atomic.c"
"esp_ble_mesh/mesh_common/mesh_buf.c"
"esp_ble_mesh/mesh_common/mesh_common.c"
Expand Down
2 changes: 2 additions & 0 deletions components/bt/component.mk
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ endif

ifdef CONFIG_BLE_MESH
COMPONENT_ADD_INCLUDEDIRS += esp_ble_mesh/mesh_common/include \
esp_ble_mesh/mesh_common/tinycrypt/include \
esp_ble_mesh/mesh_core \
esp_ble_mesh/mesh_core/include \
esp_ble_mesh/mesh_core/storage \
Expand All @@ -151,6 +152,7 @@ COMPONENT_ADD_INCLUDEDIRS += esp_ble_mesh/mesh_common/include \
esp_ble_mesh/api

COMPONENT_SRCDIRS += esp_ble_mesh/mesh_common \
esp_ble_mesh/mesh_common/tinycrypt/src \
esp_ble_mesh/mesh_core \
esp_ble_mesh/mesh_core/storage \
esp_ble_mesh/btc \
Expand Down
9 changes: 0 additions & 9 deletions components/bt/esp_ble_mesh/mesh_common/include/mesh_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,15 +185,6 @@ const char *bt_hex(const void *buf, size_t len);

void mem_rcopy(u8_t *dst, u8_t const *src, u16_t len);

unsigned int _copy(uint8_t *to, unsigned int to_len,
const uint8_t *from, unsigned int from_len);

void _set(void *to, uint8_t val, unsigned int len);

uint8_t _double_byte(uint8_t a);

int _compare(const uint8_t *a, const uint8_t *b, size_t size);

#ifdef __cplusplus
}
#endif
Expand Down
39 changes: 0 additions & 39 deletions components/bt/esp_ble_mesh/mesh_common/mesh_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@

#include "mesh_types.h"
#include "mesh_util.h"
#include "mesh_aes_encrypt.h"

#define MASK_TWENTY_SEVEN 0x1b

const char *bt_hex(const void *buf, size_t len)
{
Expand Down Expand Up @@ -45,39 +42,3 @@ void mem_rcopy(u8_t *dst, u8_t const *src, u16_t len)
*dst++ = *--src;
}
}

unsigned int _copy(uint8_t *to, unsigned int to_len,
const uint8_t *from, unsigned int from_len)
{
if (from_len <= to_len) {
(void)memcpy(to, from, from_len);
return from_len;
} else {
return TC_CRYPTO_FAIL;
}
}

void _set(void *to, uint8_t val, unsigned int len)
{
(void)memset(to, val, len);
}

/*
* Doubles the value of a byte for values up to 127.
*/
uint8_t _double_byte(uint8_t a)
{
return ((a << 1) ^ ((a >> 7) * MASK_TWENTY_SEVEN));
}

int _compare(const uint8_t *a, const uint8_t *b, size_t size)
{
const uint8_t *tempa = a;
const uint8_t *tempb = b;
uint8_t result = 0;

for (unsigned int i = 0; i < size; i++) {
result |= tempa[i] ^ tempb[i];
}
return result;
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,10 @@
* 2) call tc_aes_encrypt/decrypt to process the data.
*/

#ifndef _BLE_MESH_AES_ENCRYPT_H_
#define _BLE_MESH_AES_ENCRYPT_H_
#ifndef __BLE_MESH_TC_AES_H__
#define __BLE_MESH_TC_AES_H__

#include <stdint.h>
#include <stddef.h>

#ifdef __cplusplus
extern "C" {
Expand All @@ -59,41 +58,13 @@ extern "C" {
#define Nb (4) /* number of columns (32-bit words) comprising the state */
#define Nk (4) /* number of 32-bit words comprising the key */
#define Nr (10) /* number of rounds */
#define TC_AES_BLOCK_SIZE (Nb*Nk)
#define TC_AES_KEY_SIZE (Nb*Nk)

#define TC_CRYPTO_SUCCESS 1
#define TC_CRYPTO_FAIL 0

#define TC_ZERO_BYTE 0x00

/* padding for last message block */
#define TC_CMAC_PADDING 0x80
#define TC_AES_BLOCK_SIZE (Nb*Nk)
#define TC_AES_KEY_SIZE (Nb*Nk)

typedef struct tc_aes_key_sched_struct {
unsigned int words[Nb * (Nr + 1)];
} *TCAesKeySched_t;

/* struct tc_cmac_struct represents the state of a CMAC computation */
typedef struct tc_cmac_struct {
/* initialization vector */
uint8_t iv[TC_AES_BLOCK_SIZE];
/* used if message length is a multiple of block_size bytes */
uint8_t K1[TC_AES_BLOCK_SIZE];
/* used if message length isn't a multiple block_size bytes */
uint8_t K2[TC_AES_BLOCK_SIZE];
/* where to put bytes that didn't fill a block */
uint8_t leftover[TC_AES_BLOCK_SIZE];
/* identifies the encryption key */
unsigned int keyid;
/* next available leftover location */
unsigned int leftover_offset;
/* AES key schedule */
TCAesKeySched_t sched;
/* calls to tc_cmac_update left before re-key */
uint64_t countdown;
} *TCCmacState_t;

/**
* @brief Set AES-128 encryption key
* Uses key k to initialize s
Expand Down Expand Up @@ -152,20 +123,8 @@ int tc_aes128_set_decrypt_key(TCAesKeySched_t s, const uint8_t *k);
int tc_aes_decrypt(uint8_t *out, const uint8_t *in,
const TCAesKeySched_t s);

int tc_cmac_setup(TCCmacState_t s, const uint8_t *key, TCAesKeySched_t sched);

void gf_double(uint8_t *out, uint8_t *in);

int tc_cmac_init(TCCmacState_t s);

int tc_cmac_update(TCCmacState_t s, const uint8_t *data, size_t data_length);

int tc_cmac_final(uint8_t *tag, TCCmacState_t s);

int tc_cmac_erase(TCCmacState_t s);

#ifdef __cplusplus
}
#endif

#endif /* _BLE_MESH_AES_ENCRYPT_H_ */
#endif /* __BLE_MESH_TC_AES_H__ */
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/* cbc_mode.h - TinyCrypt interface to a CBC mode implementation */

/*
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

/**
* @file
* @brief Interface to a CBC mode implementation.
*
* Overview: CBC (for "cipher block chaining") mode is a NIST approved mode of
* operation defined in SP 800-38a. It can be used with any block
* cipher to provide confidentiality of strings whose lengths are
* multiples of the block_size of the underlying block cipher.
* TinyCrypt hard codes AES as the block cipher.
*
* Security: CBC mode provides data confidentiality given that the maximum
* number q of blocks encrypted under a single key satisfies
* q < 2^63, which is not a practical constraint (it is considered a
* good practice to replace the encryption when q == 2^56). CBC mode
* provides NO data integrity.
*
* CBC mode assumes that the IV value input into the
* tc_cbc_mode_encrypt is randomly generated. The TinyCrypt library
* provides HMAC-PRNG module, which generates suitable IVs. Other
* methods for generating IVs are acceptable, provided that the
* values of the IVs generated appear random to any adversary,
* including someone with complete knowledge of the system design.
*
* The randomness property on which CBC mode's security depends is
* the unpredictability of the IV. Since it is unpredictable, this
* means in practice that CBC mode requires that the IV is stored
* somehow with the ciphertext in order to recover the plaintext.
*
* TinyCrypt CBC encryption prepends the IV to the ciphertext,
* because this affords a more efficient (few buffers) decryption.
* Hence tc_cbc_mode_encrypt assumes the ciphertext buffer is always
* 16 bytes larger than the plaintext buffer.
*
* Requires: AES-128
*
* Usage: 1) call tc_cbc_mode_encrypt to encrypt data.
*
* 2) call tc_cbc_mode_decrypt to decrypt data.
*
*/

#ifndef __BLE_MESH_TC_CBC_MODE_H__
#define __BLE_MESH_TC_CBC_MODE_H__

#include <tinycrypt/aes.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief CBC encryption procedure
* CBC encrypts inlen bytes of the in buffer into the out buffer
* using the encryption key schedule provided, prepends iv to out
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if:
* out == NULL or
* in == NULL or
* ctr == NULL or
* sched == NULL or
* inlen == 0 or
* (inlen % TC_AES_BLOCK_SIZE) != 0 or
* (outlen % TC_AES_BLOCK_SIZE) != 0 or
* outlen != inlen + TC_AES_BLOCK_SIZE
* @note Assumes: - sched has been configured by aes_set_encrypt_key
* - iv contains a 16 byte random string
* - out buffer is large enough to hold the ciphertext + iv
* - out buffer is a contiguous buffer
* - in holds the plaintext and is a contiguous buffer
* - inlen gives the number of bytes in the in buffer
* @param out IN/OUT -- buffer to receive the ciphertext
* @param outlen IN -- length of ciphertext buffer in bytes
* @param in IN -- plaintext to encrypt
* @param inlen IN -- length of plaintext buffer in bytes
* @param iv IN -- the IV for the this encrypt/decrypt
* @param sched IN -- AES key schedule for this encrypt
*/
int tc_cbc_mode_encrypt(uint8_t *out, unsigned int outlen, const uint8_t *in,
unsigned int inlen, const uint8_t *iv,
const TCAesKeySched_t sched);

/**
* @brief CBC decryption procedure
* CBC decrypts inlen bytes of the in buffer into the out buffer
* using the provided encryption key schedule
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if:
* out == NULL or
* in == NULL or
* sched == NULL or
* inlen == 0 or
* outlen == 0 or
* (inlen % TC_AES_BLOCK_SIZE) != 0 or
* (outlen % TC_AES_BLOCK_SIZE) != 0 or
* outlen != inlen + TC_AES_BLOCK_SIZE
* @note Assumes:- in == iv + ciphertext, i.e. the iv and the ciphertext are
* contiguous. This allows for a very efficient decryption
* algorithm that would not otherwise be possible
* - sched was configured by aes_set_decrypt_key
* - out buffer is large enough to hold the decrypted plaintext
* and is a contiguous buffer
* - inlen gives the number of bytes in the in buffer
* @param out IN/OUT -- buffer to receive decrypted data
* @param outlen IN -- length of plaintext buffer in bytes
* @param in IN -- ciphertext to decrypt, including IV
* @param inlen IN -- length of ciphertext buffer in bytes
* @param iv IN -- the IV for the this encrypt/decrypt
* @param sched IN -- AES key schedule for this decrypt
*
*/
int tc_cbc_mode_decrypt(uint8_t *out, unsigned int outlen, const uint8_t *in,
unsigned int inlen, const uint8_t *iv,
const TCAesKeySched_t sched);

#ifdef __cplusplus
}
#endif

#endif /* __BLE_MESH_TC_CBC_MODE_H__ */
Loading

0 comments on commit f9cee60

Please sign in to comment.