From f0e18fa007335a5ace2cd202cbd48e2e392c9315 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Thu, 29 Mar 2018 17:23:54 +0100 Subject: [PATCH] BLE: Add LESC crypto toolbox for Nordic. --- .../TARGET_NRF5/source/nRF5XCrypto.cpp | 140 ++++++++++++++++++ .../TARGET_NRF5/source/nRF5xCrypto.h | 71 +++++++++ 2 files changed, 211 insertions(+) create mode 100644 features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5XCrypto.cpp create mode 100644 features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xCrypto.h diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5XCrypto.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5XCrypto.cpp new file mode 100644 index 0000000000..9c6cb00232 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5XCrypto.cpp @@ -0,0 +1,140 @@ +#include + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif +#include +#include + + +#include "mbedtls/platform.h" +#include "mbedtls/ecdh.h" +#include "mbedtls/memory_buffer_alloc.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ecp.h" + +#include "platform/NonCopyable.h" +#include "platform/CriticalSectionLock.h" +#include "ble/BLETypes.h" +#include "cmsis.h" +#include "nRF5xCrypto.h" + +namespace ble { +namespace pal { +namespace vendor { +namespace nordic { + +LescCrypto::LescCrypto() : _initialized(false) { + mbedtls_entropy_init(&_entropy_context); + mbedtls_ecp_group_init(&_group); + int err = mbedtls_ecp_group_load( + &_group, + MBEDTLS_ECP_DP_SECP256R1 + ); + _initialized = err ? false : true; +} + +LescCrypto::~LescCrypto() { + mbedtls_ecp_group_free(&_group); + mbedtls_entropy_free(&_entropy_context); +} + +bool LescCrypto::generate_keys( + ble::public_key_coord_t& X, + ble::public_key_coord_t& Y, + ble::public_key_coord_t& secret +) { + mbedtls_mpi secret_key; + mbedtls_ecp_point public_keys; + + mbedtls_mpi_init(&secret_key); + mbedtls_ecp_point_init(&public_keys); + + int err = mbedtls_ecp_gen_keypair( + &_group, + &secret_key, + &public_keys, + mbedtls_entropy_func, + &_entropy_context + ); + + if (!err) { + store_mpi(secret, secret_key); + store_mpi(X, public_keys.X); + store_mpi(Y, public_keys.Y); + } + + mbedtls_ecp_point_free(&public_keys); + mbedtls_mpi_free(&secret_key); + + return err ? false : true; +} + +bool LescCrypto::generate_shared_secret( + const ble::public_key_coord_t& peer_X, + const ble::public_key_coord_t& peer_Y, + const ble::public_key_coord_t& own_secret, + ble::public_key_coord_t& shared_secret +) { + mbedtls_mpi result; + mbedtls_mpi secret_key; + mbedtls_ecp_point public_keys; + + mbedtls_mpi_init(&result); + mbedtls_mpi_init(&secret_key); + mbedtls_ecp_point_init(&public_keys); + + load_mpi(secret_key, own_secret); + load_mpi(public_keys.X, peer_X); + load_mpi(public_keys.Y, peer_Y); + mbedtls_mpi_lset( &public_keys.Z, 1 ); + + int err = mbedtls_ecdh_compute_shared( + &_group, + &result, + &public_keys, + &secret_key, + /* rng function; optional */ NULL, + /* rng param */ NULL + ); + + if (!err) { + store_mpi(shared_secret, result); + } + + mbedtls_ecp_point_free(&public_keys); + mbedtls_mpi_free(&secret_key); + mbedtls_mpi_free(&result); + + return err ? false : true; +} + + +void LescCrypto::load_mpi(mbedtls_mpi& dest, const ble::public_key_coord_t& src) { + ble::public_key_coord_t src_be = src; + swap_endian(src_be); + mbedtls_mpi_read_binary(&dest, src_be.buffer(), src_be.size()); +} + +void LescCrypto::store_mpi(ble::public_key_coord_t& dest, const mbedtls_mpi& src) { + mbedtls_mpi_write_binary(&src, dest.buffer(), dest.size()); + swap_endian(dest); +} + +void LescCrypto::swap_endian(ble::public_key_coord_t& to_swap) { + swap_endian(to_swap.buffer(), to_swap.size()); +} + +void LescCrypto::swap_endian(uint8_t* buf, size_t len) { + for(size_t low = 0, high = (len - 1); high > low; --high, ++low) { + std::swap(buf[low], buf[high]); + } +} + +} // nordic +} // vendor +} // pal +} // ble + diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xCrypto.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xCrypto.h new file mode 100644 index 0000000000..1478d4213f --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xCrypto.h @@ -0,0 +1,71 @@ +#ifndef NRF5X_CRYPTO_ +#define NRF5X_CRYPTO_ + +#include + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif +#include +#include + + +#include "mbedtls/platform.h" +#include "mbedtls/ecdh.h" +#include "mbedtls/memory_buffer_alloc.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ecp.h" + +#include "platform/NonCopyable.h" +#include "platform/CriticalSectionLock.h" +#include "ble/BLETypes.h" +#include "cmsis.h" + +namespace ble { +namespace pal { +namespace vendor { +namespace nordic { + +class LescCrypto : mbed::NonCopyable { + +public: + LescCrypto(); + + ~LescCrypto(); + + bool generate_keys( + ble::public_key_coord_t& X, + ble::public_key_coord_t& Y, + ble::public_key_coord_t& secret + ); + + bool generate_shared_secret( + const ble::public_key_coord_t& peer_X, + const ble::public_key_coord_t& peer_Y, + const ble::public_key_coord_t& own_secret, + ble::public_key_coord_t& shared_secret + ); + +private: + + void load_mpi(mbedtls_mpi& dest, const ble::public_key_coord_t& src); + + void store_mpi(ble::public_key_coord_t& dest, const mbedtls_mpi& src); + + void swap_endian(ble::public_key_coord_t& to_swap); + + void swap_endian(uint8_t* buf, size_t len); + + bool _initialized; + mbedtls_entropy_context _entropy_context; + mbedtls_ecp_group _group; +}; + +} // nordic +} // vendor +} // pal +} // ble + +#endif // NRF5X_CRYPTO_