Skip to content

Commit

Permalink
Move TI hardware acceleration into Matter repo (#9579)
Browse files Browse the repository at this point in the history
Moved the SHA, AES, and ECJPAKE alt headers and source files into the Matter
repository. Fixed an issue with the semantics of SHA256 context cloning.
Changed the CHIPCryptoPALmbedTLS.cpp implementation to clone the temporary
context back over the original context when done with the non-final
finalization. Increased the SHA context opaque size in CHIPCryptoPAL.h to fit
the TI driver accelerated SHA context.

In future commits it may be possible to share a single SHA driver instance
between all the contexts in mbedtls. This has the disadvantage of requiring a
mutex for driver usage and reference counting. This would also increase
processing time due to the thrashing of the internal digest buffer. But has the
potential advantage that the SHA context can be copied directly with a memcpy.

The Hash_SHA256_stream object is now created on the stack and let to fall out
of context at the end of a translation unit. This causes an issue if the
resources are not freed. Update the mbedtls PAL to initialize and free the
underlying SHA context structure.
  • Loading branch information
srickardti authored Oct 8, 2021
1 parent 6f73ebc commit c4bf82e
Show file tree
Hide file tree
Showing 14 changed files with 1,493 additions and 39 deletions.
15 changes: 3 additions & 12 deletions src/crypto/CHIPCryptoPAL.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include <crypto/CryptoBuildConfig.h>
#endif

#include <system/SystemConfig.h>

#include <lib/core/CHIPError.h>
#include <lib/core/CHIPVendorIdentifiers.hpp>
#include <lib/support/CodeUtils.h>
Expand Down Expand Up @@ -80,18 +82,7 @@ constexpr size_t kMAX_P256Keypair_Context_Size = 512;
constexpr size_t kEmitDerIntegerWithoutTagOverhead = 1; // 1 sign stuffer
constexpr size_t kEmitDerIntegerOverhead = 3; // Tag + Length byte + 1 sign stuffer

/*
* Worst case is OpenSSL, so let's use its worst case and let static assert tell us if
* we are wrong, since `typedef SHA_LONG unsigned int` is default.
* SHA_LONG h[8];
* SHA_LONG Nl, Nh;
* SHA_LONG data[SHA_LBLOCK]; // SHA_LBLOCK is 16 for SHA256
* unsigned int num, md_len;
*
* We also have to account for possibly some custom extensions on some targets,
* especially for mbedTLS, so an extra sizeof(uint64_t) is added to account.
*/
constexpr size_t kMAX_Hash_SHA256_Context_Size = ((sizeof(unsigned int) * (8 + 2 + 16 + 2)) + sizeof(uint64_t));
constexpr size_t kMAX_Hash_SHA256_Context_Size = CHIP_CONFIG_SHA256_CONTEXT_SIZE;

/*
* Overhead to encode a raw ECDSA signature in X9.62 format in ASN.1 DER
Expand Down
22 changes: 14 additions & 8 deletions src/crypto/CHIPCryptoPALmbedTLS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,13 +207,6 @@ CHIP_ERROR Hash_SHA1(const uint8_t * data, const size_t data_length, uint8_t * o
return CHIP_NO_ERROR;
}

Hash_SHA256_stream::Hash_SHA256_stream(void) {}

Hash_SHA256_stream::~Hash_SHA256_stream(void)
{
Clear();
}

static_assert(kMAX_Hash_SHA256_Context_Size >= sizeof(mbedtls_sha256_context),
"kMAX_Hash_SHA256_Context_Size is too small for the size of underlying mbedtls_sha256_context");

Expand All @@ -222,6 +215,19 @@ static inline mbedtls_sha256_context * to_inner_hash_sha256_context(HashSHA256Op
return SafePointerCast<mbedtls_sha256_context *>(context);
}

Hash_SHA256_stream::Hash_SHA256_stream(void)
{
mbedtls_sha256_context * context = to_inner_hash_sha256_context(&mContext);
mbedtls_sha256_init(context);
}

Hash_SHA256_stream::~Hash_SHA256_stream(void)
{
mbedtls_sha256_context * context = to_inner_hash_sha256_context(&mContext);
mbedtls_sha256_free(context);
Clear();
}

CHIP_ERROR Hash_SHA256_stream::Begin(void)
{
mbedtls_sha256_context * const context = to_inner_hash_sha256_context(&mContext);
Expand Down Expand Up @@ -254,7 +260,7 @@ CHIP_ERROR Hash_SHA256_stream::GetDigest(MutableByteSpan & out_buffer)
CHIP_ERROR result = Finish(out_buffer);

// Restore context prior to finalization.
*context = previous_ctx;
mbedtls_sha256_clone(context, &previous_ctx);

return result;
}
Expand Down
22 changes: 22 additions & 0 deletions src/lib/core/CHIPConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,28 @@
#error "Please assert exactly one CHIP_CONFIG_HASH_IMPLEMENTATION_... option."
#endif

/**
* @def CHIP_CONFIG_SHA256_CONTEXT_SIZE
*
* @brief
* Size of the statically allocated context for SHA256 operations in CryptoPAL
*
* The default size is based on the Worst software implementation, OpenSSL. A
* static assert will tell us if we are wrong, since `typedef SHA_LONG unsigned
* int` is default.
* SHA_LONG h[8];
* SHA_LONG Nl, Nh;
* SHA_LONG data[SHA_LBLOCK]; // SHA_LBLOCK is 16 for SHA256
* unsigned int num, md_len;
*
* We also have to account for possibly some custom extensions on some targets,
* especially for mbedTLS, so an extra sizeof(uint64_t) is added to account.
*
*/
#ifndef CHIP_CONFIG_SHA256_CONTEXT_SIZE
#define CHIP_CONFIG_SHA256_CONTEXT_SIZE ((sizeof(unsigned int) * (8 + 2 + 16 + 2)) + sizeof(uint64_t))
#endif // CHIP_CONFIG_SHA256_CONTEXT_SIZE

/**
* @name chip key export protocol configuration.
*
Expand Down
15 changes: 5 additions & 10 deletions src/platform/cc13x2_26x2/BLEManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,34 +22,31 @@
* Instruments cc13xx_cc26xx platform.
*/

#ifndef BLEManager_IMPL_H
#define BLEManager_IMPL_H

#pragma once

#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE

#ifdef __cplusplus
extern "C" {
#endif

#include "FreeRTOS.h"
#include <queue.h>
#include <task.h>

#ifdef __cplusplus
extern "C" {
#endif
#include <icall.h>
#include <icall_ble_api.h>

#include "hal_types.h"

#include "chipOBleProfile.h"
#include "ti_ble_config.h"
#include "ti_drivers_config.h"

#ifdef __cplusplus
}
#endif

#include "chipOBleProfile.h"

namespace chip {
namespace DeviceLayer {
namespace Internal {
Expand Down Expand Up @@ -367,5 +364,3 @@ inline BleLayer * BLEManagerImpl::_GetBleLayer()
} // namespace chip

#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE

#endif // BLEManager_IMPL_H
7 changes: 5 additions & 2 deletions src/platform/cc13x2_26x2/CHIPPlatformConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,17 @@

// ==================== Security Adaptations ====================

// This platform uses mbedtls, but these defines don't seem to be used in source
#define CHIP_CONFIG_USE_OPENSSL_ECC 0
#define CHIP_CONFIG_USE_MICRO_ECC 1

#define CHIP_CONFIG_HASH_IMPLEMENTATION_OPENSSL 0
#define CHIP_CONFIG_HASH_IMPLEMENTATION_MINCRYPT 1
#define CHIP_CONFIG_HASH_IMPLEMENTATION_MBEDTLS 0
#define CHIP_CONFIG_HASH_IMPLEMENTATION_MINCRYPT 0
#define CHIP_CONFIG_HASH_IMPLEMENTATION_MBEDTLS 1
#define CHIP_CONFIG_HASH_IMPLEMENTATION_PLATFORM 0

#define CHIP_CONFIG_SHA256_CONTEXT_SIZE (sizeof(unsigned int) * 76)

#define CHIP_CONFIG_AES_IMPLEMENTATION_OPENSSL 0
#define CHIP_CONFIG_AES_IMPLEMENTATION_AESNI 0
#define CHIP_CONFIG_AES_IMPLEMENTATION_MBEDTLS 1
Expand Down
135 changes: 135 additions & 0 deletions src/platform/cc13x2_26x2/crypto/aes_alt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2020 Texas Instruments Incorporated
*
* 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 "aes_alt.h"
#include "mbedtls/aes.h"

#if defined(MBEDTLS_AES_ALT)

#include <string.h>

#include "ti_drivers_config.h"

#include <ti/devices/DeviceFamily.h>
#include <ti/drivers/AESECB.h>
#include <ti/drivers/cryptoutils/cryptokey/CryptoKeyPlaintext.h>

/*
* number of active contexts, used for power on/off of the crypto core
*/
static unsigned int ref_num = 0;

static AESECB_Handle AESECB_handle = NULL;

void mbedtls_aes_init(mbedtls_aes_context * ctx)
{
AESECB_Params AESECBParams;

if (ref_num == 0)
{
AESECB_Params_init(&AESECBParams);
AESECBParams.returnBehavior = AESECB_RETURN_BEHAVIOR_POLLING;
AESECB_handle = AESECB_open(CONFIG_AESECB_1, &AESECBParams);

// handle will be NULL if open failed, subsequent calls will fail with a generic HW error
}
ref_num++;
}

void mbedtls_aes_free(mbedtls_aes_context * ctx)
{
if (ref_num > 0)
{
ref_num--;
if (ref_num == 0)
{
AESECB_close(AESECB_handle);

AESECB_handle = NULL;
}
}

memset((void *) ctx, 0x00, sizeof(ctx));
}

int mbedtls_aes_setkey_enc(mbedtls_aes_context * ctx, const unsigned char * key, unsigned int keybits)
{
int_fast16_t statusCrypto;
size_t keylen = keybits / 8U; // 8 bits in a byte

if (keylen > sizeof(ctx->keyMaterial))
{
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
}

/* Initialize AES key */
memcpy(ctx->keyMaterial, key, keylen);
statusCrypto = CryptoKeyPlaintext_initKey(&ctx->cryptoKey, (uint8_t *) ctx->keyMaterial, keylen);

if (CryptoKey_STATUS_SUCCESS != statusCrypto)
{
return MBEDTLS_ERR_AES_HW_ACCEL_FAILED;
}

return 0;
}

int mbedtls_aes_setkey_dec(mbedtls_aes_context * ctx, const unsigned char * key, unsigned int keybits)
{
int_fast16_t statusCrypto;
size_t keylen = keybits / 8U; // 8 bits in a byte

if (keylen > sizeof(ctx->keyMaterial))
{
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
}

/* Initialize AES key */
statusCrypto = CryptoKeyPlaintext_initKey(&ctx->cryptoKey, (uint8_t *) key, keylen);

if (CryptoKey_STATUS_SUCCESS != statusCrypto)
{
return MBEDTLS_ERR_AES_HW_ACCEL_FAILED;
}

return 0;
}

int mbedtls_aes_crypt_ecb(mbedtls_aes_context * ctx, int mode, const unsigned char input[16], unsigned char output[16])
{
int statusCrypto;
AESECB_Operation operationOneStepEncrypt;

/* run it through the authentication + encryption, pass the ccmLVal = 2 */
AESECB_Operation_init(&operationOneStepEncrypt);

operationOneStepEncrypt.key = &ctx->cryptoKey;
operationOneStepEncrypt.inputLength = 16;
operationOneStepEncrypt.input = (uint8_t *) input;
operationOneStepEncrypt.output = (uint8_t *) output;

statusCrypto = AESECB_oneStepEncrypt(AESECB_handle, &operationOneStepEncrypt);

if (CryptoKey_STATUS_SUCCESS != statusCrypto)
{
return MBEDTLS_ERR_AES_HW_ACCEL_FAILED;
}

return 0;
}
#endif
46 changes: 46 additions & 0 deletions src/platform/cc13x2_26x2/crypto/aes_alt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2020 Texas Instruments Incorporated
*
* 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

#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls-config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

#if defined(MBEDTLS_AES_ALT)

#include <ti/drivers/AESECB.h>
#include <ti/drivers/cryptoutils/cryptokey/CryptoKey.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct
{
CryptoKey cryptoKey; /*!< structure for the AES driver */
uint32_t keyMaterial[16]; /*!< memory for the key bytes used by cryptoKey */
} mbedtls_aes_context;

#ifdef __cplusplus
}
#endif

#endif /* MBEDTLS_AES_ALT */
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
#define MBEDTLS_ECJPAKE_ALT
#define MBEDTLS_AES_ALT
#define MBEDTLS_SHA256_ALT
//#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_ENTROPY_HARDWARE_ALT

/**
* Enable Crypto and Entropy modules
Expand Down
Loading

0 comments on commit c4bf82e

Please sign in to comment.