Skip to content

Commit

Permalink
First commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
petertorelli committed Jun 18, 2020
0 parents commit bc43444
Show file tree
Hide file tree
Showing 68 changed files with 24,112 additions and 0 deletions.
136 changes: 136 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
---
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: true
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: TopLevel
AlwaysBreakAfterReturnType: TopLevelDefinitions
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: false
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: true
BeforeElse: true
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: All
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeComma
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: true
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
- Regex: '.*'
Priority: 1
SortPriority: 0
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: true
IndentGotoLabels: true
IndentPPDirectives: None
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: false
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Right
ReflowComments: true
SortIncludes: false
SortUsingDeclarations: false
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Latest
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseCRLF: false
UseTab: Never
...

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build
100 changes: 100 additions & 0 deletions LICENSE.md

Large diffs are not rendered by default.

56 changes: 56 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Introduction

EEMBC® SecureMark™ is an objective, standardized benchmarking framework for measuring the efficiency of cryptographic processing solutions. Within SecureMark, EEMBC plans to support test and analysis of various security profiles for different application domains. The first version is called SecureMark-TLS, which focuses on Transport Layer Security (TLS) for internet of things (IoT) edge nodes.

This repository contains the SecureMark-TLS firmware for *standalone* execution, which does not require the external hardware test-harness, nor the host GUI software. This means you can run the benchmark and collect just performance scores. In order collect official energy scores and upload them to the EEMBC website, you will need both the hardware for the test-harness and a license for the host software. While this is still the same benchmark workload, the host software is needed to determines the run was valid (i.e. to discourage cheating and verify adherence to the "Run Rules"), and the test-harness is needed to collect the measurements required to compute the energy-efficiency score.

# Firmware

The firmware is divided into two sections: the `monitor` and the `profile`. The `monitor` contains a basic API to the device under test (DUT), and the `profile` contains the actual benchmark code and algorithm API. In the code, files and functions that start with `ee_` cannot be changed, whereas those which begin with `th_` in most cases must be edited, as they are empty hardware-specific implementation layers.

## Monitor

The monitor provides a basic set of platform requirements to communicate with the device under test (DUT). This includes a UART interface, a 1-ms timer, and a GPIO used for external triggering. The selfhosted example uses console I/O and a system timer to take the place of the hardware requirements.

## Profile

The profile contains the components from which the final benchmark score is comprised. By calling these components with different configurations, the SecureMark-TLS benchmark emulates a TLS handshake and data transfer using the following cryptoprimitives:

* Ephemeral ECDH key exchange,
* ECDSA with a SHA256 HMAC,
* SHA256 hashing, and
* both AES 128 CCM and ECB exchanges

These primitives were selected because they resemble what is most popular in the constrained IoT space at this time.

In order to analyze energy efficiency, the API provides a thin layer to each primitive which can be implemented with software -or- hardware. This allows enormous flexibility: the same platform can be tested with and without hardware acceleration by a few changes to the underlying implementation layer.

A TLS handshake with this configuration has 14 steps and generates over a dozen different contexts with various-sized payloads. The firmware API allows the host software to configure and execute these primitives with different input data sizes in order to both emulate the handshake for an official score, and to provide exploration and analysis outside the scope of the benchmark. (The host GUI provides additional dynamic configuration options than the self-hosted code.)

The high-level wrapper for each primitive is implemented in the `profile/ee_*` files. The `profiles/th_api/th_*` files provide the user implementation. In the `examples` folder, the self-hosted code implements the `th_*` functionality with Arm's mbedTLS(tm) library. A version of mbedTLS has been provided for completeness, but this is just one possible implementation. A developer could use wolfSSL or LibTomCrypt, or the hardware acceleration libraries found on many Arm-based MCU and SoC products. The EEMBC API makes porting quick and easy.

## Scoring

By design, the profile firmware only contains the primitives for the test, and not the actual test sequence itself. Normally this is controlled by the host software, which also provides additional analysis capabilities. However, in this repository, the self-hosted version invokes each primitive with the correct number of iterations, and summarizes the performance results according on its own.

The *performance* score of the benchmark is the sum of the weighted runtimes, inverted (so that decreasing time indicates increasing score), and then multiplied by 1000 to scale into an integer range.

Similarly, the *energy* score is the sum of the weighted Joule consumption.

The weighted values were determined by vote in the SecureMark working group.

## Examples

See the README in the `examples` folder for information on building the self-hosted benchmark.

# Full Version

To obtain the host GUI, user manual, and bill-of-materials for the EEMBC IoTConnect test-harness framework, please contact [support@eembc.org](mailto:support@eembc.org).

# Licensing

This software is provided under an extended Apache-2.0 license. The extension includes an "Acceptable Use Agreement", which in the shortest possible terms prevents someone from changing the code and calling it SecureMark, which would diminish EEMBC's efforts at standardization. Please review the attached license before you begin.

# About EEMBC

Founded in 1997, EEMBC is US non-profit which develops benchmarks for the hardware and software used in autonomous driving, mobile imaging, the Internet of Things, mobile devices, and many other applications. The EEMBC community includes member companies, commercial licensees, and academic licensees at institutions of higher learning around the world. Visit our [website](https://www.eembc.org).
87 changes: 87 additions & 0 deletions examples/selfhosted/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
cmake_minimum_required(VERSION 3.14.0)
project(sec-tls
DESCRIPTION "Firmware for the SecureMark-TLS Self-Hosted Benchmark"
LANGUAGES C
VERSION 1.0.2)

option(SELFHOSTED "Set to '1' to build self-hosted binary, '0' by default makes a library" 0)

include(cmake/splint.cmake)

# Cross compiling with cmake (a possible example)
#set(tools /Users/ptorelli/dev/gcc-arm-none-eabi-8-2018-q4-major)
#set(CMAKE_C_COMPILER ${tools}/bin/arm-none-eabi-gcc)
#set(CMAKE_RANLIB ${tools}/bin/arm-none-eabi-ranlib)
#set(CMAKE_AR ${tools}/bin/arm-none-eabi-ar)
#set(CMAKE_LINKER ${tools}/bin/arm-none-eabi-ld)
#set(CMAKE_STRIP ${tools}/bin/arm-none-eabi-strip)
#set(CMAKE_NM ${tools}/bin/arm-none-eabi-nm)
#set(CMAKE_OBJDUMP ${tools}/bin/arm-none-eabi-objdump)

set(CMAKE_C_FLAGS "-pedantic -Wall -std=c99 -O3")

include_directories(../../monitor)
include_directories(../../monitor/th_api)
include_directories(../../profile)

if (SELFHOSTED)
include_directories(profile/th_api)
include_directories(profile/th_api/redist)
set(SOURCE
../../profile/ee_aes.c
../../profile/ee_ecdsa.c
../../profile/ee_variations.c
../../profile/ee_ecdh.c
../../profile/ee_profile.c
../../profile/ee_sha.c
profile/th_api/th_aes.c
profile/th_api/redist/mbedtls/aes.c
profile/th_api/redist/mbedtls/ecdh.c
profile/th_api/redist/mbedtls/cipher_wrap.c
profile/th_api/redist/mbedtls/hmac_drbg.c
profile/th_api/redist/mbedtls/asn1parse.c
profile/th_api/redist/mbedtls/asn1write.c
profile/th_api/redist/mbedtls/ccm.c
profile/th_api/redist/mbedtls/bignum.c
profile/th_api/redist/mbedtls/md_wrap.c
profile/th_api/redist/mbedtls/ecp.c
profile/th_api/redist/mbedtls/sha256.c
profile/th_api/redist/mbedtls/ecp_curves.c
profile/th_api/redist/mbedtls/md.c
profile/th_api/redist/mbedtls/cipher.c
profile/th_api/redist/mbedtls/ecdsa.c
profile/th_api/th_util.c
profile/th_api/th_ecdh.c
profile/th_api/th_ecdsa.c
profile/th_api/th_sha.c
../../monitor/ee_main.c
../../monitor/th_api/th_lib.c
../../monitor/th_api/th_libc.c
main.c
)
add_definitions(-DEE_CFG_SELFHOSTED=1)
add_definitions(-DEE_CFG_QUIET=1)
add_executable(sec-tls ${SOURCE})
else()
include_directories(../../monitor/th_api)
include_directories(../../profile/th_api)
set(SOURCE
../../profile/ee_aes.c
../../profile/ee_ecdsa.c
../../profile/ee_variations.c
../../profile/ee_ecdh.c
../../profile/ee_profile.c
../../profile/ee_sha.c
../../profile/th_api/th_aes.c
../../profile/th_api/th_sha.c
../../profile/th_api/th_util.c
../../profile/th_api/th_ecdh.c
../../profile/th_api/th_ecdsa.c
../../monitor/ee_main.c
../../monitor/th_api/th_lib.c
../../monitor/th_api/th_libc.c
)
add_library(sec-tls ${SOURCE})
endif()

add_splint(sec-tls ${SOURCE})
75 changes: 75 additions & 0 deletions examples/selfhosted/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Introduction

This example implements a self-hosted version of the benchmark by including
a `main()` entrypoint with an mbedTLS crypto SDK. It does not requrie a UART
or GPIO timestamp, nor does it require the host UI. It can be compiled into
a stand-alone executable which can be run from an OS or as baremetal on an
embedded platform.

# Details

## Harness

The `th_printf` and `th_timestamp` functions are implemented in `main.c`. By
compiling with the `EE_CFG_SELFHOSTED` flag set, all of the code for the UART
is removed and replaced with these two local functions. To run the benchmark,
a set of wrapper functions in `main.c` prepare the primitives for local
execution. Keys, plaintext, and ciphertext are all generated randomly with
`ee_srand()` which is seeded with zero for each primitive invocation.

## Self-timinig

The benchmark determines the correct number of iterations automatically by
porportionally increasing the count until a minimum number of seconds (or
minimum number of iterations) elapse. See `MIN_RUNTIME_SEC` and `MIN_ITER` in
`main.c`.

## Self-checking

A set of 16-bit CRC values are provided per sub-test, precomputed by EEMBC. As
long as the seeds in the code aren't changed, these should always be the same.
This is to help verify the primitive SDK implementation is was done correctly.

# Compile and run

This example uses `cmake`. The option `SELFHOSTED` enables the `EE_CFG_SELFHOSTED`
flag in the code, and links in the local `profile/th_api` implementation (as
well as `main.c`).

```
% mkdir build
% cd build
% cmake -DSELFHOSTED=1 ..
% make
:
:
% ./sec-tls
Running each primitive for at least 1s or 10 iterations.
Component #00 ips= 1286609.125 crc=0xc7b0 expected_crc=0xc7b0
Component #01 ips= 886544.812 crc=0x5481 expected_crc=0x5481
Component #02 ips= 633161.562 crc=0x998a expected_crc=0x998a
Component #03 ips= 766433.250 crc=0xd82d expected_crc=0xd82d
Component #04 ips= 393285.844 crc=0x005b expected_crc=0x005b
Component #05 ips= 499.762 crc=0xb659 expected_crc=0xb659
Component #06 ips= 1209.260 crc=0x3a47 expected_crc=0x3a47
Component #07 ips= 344.412 crc=0x3a47 expected_crc=0x3a47
Component #08 ips= 7161712.000 crc=0x2151 expected_crc=0x2151
Component #09 ips= 2998751.750 crc=0x3b3c expected_crc=0x3b3c
Component #10 ips= 473102.938 crc=0x1d3f expected_crc=0x1d3f
Component #11 ips= 79961.562 crc=0x0000 expected_crc=0x0000
Component #12 ips= 42851.652 crc=0x9284 expected_crc=0x9284
Component #13 ips= 101118.016 crc=0x989e expected_crc=0x989e
SecureMark-TLS Score is 112677.812 marks
:
```

# Scoring

This code is provided as an example of how the benchmark operates. In order to
generate an official score, the host software must be used to verify operation
of the benchmark (to discourage cheating). Please contact
[support@eembc.org](mailto:support@eembc.org) for information on how to license the host
software.



28 changes: 28 additions & 0 deletions examples/selfhosted/cmake/splint.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
option(USE_SPLINT "Set to '1' to run splint, '0' by default" 0)
function(add_splint TARGET)
if (USE_SPLINT)
get_directory_property(include_dirs INCLUDE_DIRECTORIES)
foreach(i ${include_dirs})
list(APPEND include_flags -I${i})
endforeach()
set(SPLINT_ARGS
-preproc
-paramuse
# -mustfreefresh
# -retvalother
# -fixedformalarray
# -retvalint
# -nullret
# -compdef
# -nullpass
# -mayaliasunique
# -temptrans
)
add_custom_target(
splint-${TARGET}
COMMAND splint ${SPLINT_ARGS} ${include_flags} ${ARGN}
DEPENDS ${ARGN}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
add_dependencies(${TARGET} splint-${TARGET})
endif() # USE_SPLINT
endfunction() # add_splint
Loading

0 comments on commit bc43444

Please sign in to comment.