Skip to content

Commit de1fde5

Browse files
committed
Add a new sample application to test thread safety
1 parent d659a88 commit de1fde5

File tree

4 files changed

+207
-0
lines changed

4 files changed

+207
-0
lines changed

threading/README.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# mbed TLS threading example on mbed OS
2+
3+
This application tests the thread safety of mbed TLS within mbed OS. The computations are performed sequentially at first to generate a reference value. Thereafter the aplication performs the same computations in parallel to test thread safety.
4+
5+
## Getting started
6+
7+
Set up your environment if you have not done so already. For instructions, refer to the [main readme](../README.md).
8+
9+
## Monitoring the application
10+
11+
The output in the terminal window should be similar to this:
12+
13+
```
14+
Thread 0: Starting threads one by one...
15+
Thread 1: Done.
16+
Thread 2: Done.
17+
Thread 0: Printing hash output...
18+
Thread 0: 2794387f922b5f36953b6e02e6f499b7e1dbd19accb199192e8fd3c98c5fae7eb4f31f3c996c4ab28689eb5f137a4b947fc56a79698ca8c6ea1d3efec678a82c
19+
Thread 0: Starting threads...
20+
Thread 3: Done.
21+
Thread 4: Done.
22+
Thread 0: Printing hash output...
23+
Thread 0: 2794387f922b5f36953b6e02e6f499b7e1dbd19accb199192e8fd3c98c5fae7eb4f31f3c996c4ab28689eb5f137a4b947fc56a79698ca8c6ea1d3efec678a82c
24+
Thread 0: Done.
25+
```
26+
27+
If the second hash string doesn't match the first, then the thread safety measures are not working properly and this build of mbed TLS is not thread safe!

threading/main.cpp

+176
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
/*
2+
* An example of using mbed TLS in a thread safe manner
3+
*
4+
* Copyright (C) 2016, ARM Limited, All Rights Reserved
5+
* SPDX-License-Identifier: Apache-2.0
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
8+
* not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
20+
#include "mbed.h"
21+
#include "rtos.h"
22+
#include "mbedtls/entropy.h"
23+
#include "mbedtls/threading.h"
24+
25+
#define THREADS 2
26+
#define ROUNDS 100
27+
28+
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
29+
#define HASHSIZE 64
30+
#else
31+
#define HASHSIZE 32
32+
#endif
33+
34+
#define BUFSIZE 64
35+
#define MAIN_ID 0
36+
37+
#define THREAD_CHK(f) do { if( ( ret = f ) != osOK ) goto cleanup; } while( 0 )
38+
39+
const unsigned char data[HASHSIZE] = { 0xaa };
40+
41+
Mutex stdio_mutex;
42+
43+
mbedtls_entropy_context entropy;
44+
45+
void hexify( unsigned char *obuf, const unsigned char *ibuf, int len )
46+
{
47+
unsigned char l, h;
48+
49+
while( len != 0 )
50+
{
51+
h = *ibuf / 16;
52+
l = *ibuf % 16;
53+
54+
if( h < 10 )
55+
*obuf++ = '0' + h;
56+
else
57+
*obuf++ = 'a' + h - 10;
58+
59+
if( l < 10 )
60+
*obuf++ = '0' + l;
61+
else
62+
*obuf++ = 'a' + l - 10;
63+
64+
++ibuf;
65+
len--;
66+
}
67+
68+
*obuf = '\0';
69+
}
70+
71+
void notify( const char* message, int thread_id, const int err_code )
72+
{
73+
stdio_mutex.lock();
74+
75+
if( err_code )
76+
printf( "Thread %d: ERR - %s: %d\n\r", thread_id, message, err_code );
77+
else
78+
printf( "Thread %d: %s\n\r", thread_id, message );
79+
80+
stdio_mutex.unlock();
81+
}
82+
83+
void test_thread( void const *args )
84+
{
85+
int thread_id = *( (int*)args );
86+
int ret = 0;
87+
int i;
88+
89+
for ( i = 0; i < ROUNDS; i++ )
90+
{
91+
92+
ret = mbedtls_entropy_update_manual( &entropy, data, BUFSIZE );
93+
if( 0 != ret )
94+
{
95+
notify( "mbed TLS entropy update FAILED", thread_id, ret );
96+
return;
97+
}
98+
}
99+
100+
notify( " Done.", thread_id, 0 );
101+
}
102+
103+
int main( void )
104+
{
105+
unsigned char *hash = new unsigned char[HASHSIZE];
106+
unsigned char *output = new unsigned char[2 * HASHSIZE + 1];
107+
Thread thread[THREADS * 2];
108+
int thread_id[THREADS * 2];
109+
int ret, i;
110+
111+
/*
112+
* This calls mbedtls_threading_set_alt and tells the threading
113+
* abstraction layer in mbed TLS to use the mbed implementation.
114+
*/
115+
#if defined(MBEDTLS_THREADING_ALT)
116+
mbedtls_threading_set_mbed();
117+
#endif
118+
mbedtls_entropy_init( &entropy );
119+
120+
notify( "Starting threads one by one...", MAIN_ID, 0 );
121+
for( i = 0; i < THREADS; i++ )
122+
{
123+
thread_id[i] = i + 1;
124+
THREAD_CHK( thread[i].start( mbed::callback( test_thread, &thread_id[i] ) ) );
125+
THREAD_CHK( thread[i].join() );
126+
}
127+
128+
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
129+
mbedtls_sha512_finish( &entropy.accumulator, hash );
130+
#else
131+
mbedtls_sha256_finish( &entropy.accumulator, hash );
132+
#endif
133+
134+
hexify( output, hash, HASHSIZE );
135+
notify( "Printing hash output...", MAIN_ID, 0 );
136+
notify( (char*)output, MAIN_ID, 0 );
137+
138+
mbedtls_entropy_init( &entropy );
139+
140+
notify( "Starting threads...", MAIN_ID, 0 );
141+
for( i = THREADS; i < 2 * THREADS; i++ )
142+
{
143+
thread_id[i] = i + 1;
144+
THREAD_CHK( thread[i].start( mbed::callback( test_thread, &thread_id[i] ) ) );
145+
}
146+
147+
for( i = THREADS; i < 2 * THREADS; i++ )
148+
THREAD_CHK( thread[i].join() );
149+
150+
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
151+
mbedtls_sha512_finish( &entropy.accumulator, hash );
152+
#else
153+
mbedtls_sha256_finish( &entropy.accumulator, hash );
154+
#endif
155+
156+
hexify( output, hash, HASHSIZE );
157+
notify( "Printing hash output...", MAIN_ID, 0 );
158+
notify( (char*)output, MAIN_ID, 0 );
159+
160+
cleanup:
161+
162+
if( osOK != ret )
163+
{
164+
notify( "RTOS thread operation FAILED", MAIN_ID, ret );
165+
166+
for( i = 0; i < 2 * THREADS; i++ )
167+
thread[i].terminate();
168+
}
169+
170+
#if defined(MBEDTLS_THREADING_ALT)
171+
mbedtls_entropy_free( &entropy );
172+
#endif
173+
mbedtls_threading_free_alt();
174+
175+
notify( "Done.", MAIN_ID, 0 );
176+
}

threading/mbed-os.lib

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
https://github.com/ARMmbed/mbed-os/#e435a07d9252f133ea3d9f6c95dfb176f32ab9b6

threading/mbed_app.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"macros": ["MBEDTLS_THREADING"]
3+
}

0 commit comments

Comments
 (0)