Skip to content

Commit 90c81fb

Browse files
authored
Merge pull request #82 from ejohnstown/porting
2 parents cfe4574 + 4d05fbe commit 90c81fb

File tree

9 files changed

+409
-0
lines changed

9 files changed

+409
-0
lines changed

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,11 @@ wolfengine: PDFFILE=wolfEngine-Manual.pdf
6565
wolfengine: build
6666
@$(DOCKER_CMD)
6767

68+
.PHONY: porting
69+
porting: MANPATH=wolfSSL-Porting
70+
porting: PDFFILE=wolfSSL-Porting-Guide.pdf
71+
porting: build
72+
@$(DOCKER_CMD)
73+
6874
clean:
6975
rm -rf build

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ To build the documentation you will need Docker running on your system. In this
2020
* `make wolfsentry`
2121
* `make wolfssl-jni`
2222
* `make wolftpm`
23+
* `make porting`
2324

2425
## Contributing
2526

wolfSSL-Porting/Makefile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
-include ../common/common.am
2+
.DEFAULT_GOAL := all
3+
all: pdf html
4+
5+
6+
SOURCES = section01.md \
7+
section02.md \
8+
section03.md \
9+
section04.md
10+
11+
PDF = wolfSSL-Porting-Guide.pdf
12+
13+
.PHONY: html-prep
14+
html-prep:
15+
16+
.PHONY: pdf-prep
17+
pdf-prep:

wolfSSL-Porting/header.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
% wolfSSL Porting Guide ![](logo.png)
2+
3+
---
4+
header-includes:
5+
# Blank pages on new sections
6+
- \usepackage{titlesec}
7+
- \newcommand{\sectionbreak}{\clearpage}
8+
# Fancy page headers
9+
- \usepackage{fancyhdr}
10+
- \pagestyle{fancy}
11+
- \fancyfoot[LO,RE]{COPYRIGHT \copyright 2023 wolfSSL Inc.}
12+
# Wrap long syntax highlighting code blocks
13+
- \usepackage{fvextra}
14+
- \DefineVerbatimEnvironment{Highlighting}{Verbatim}{breaklines,commandchars=\\\{\}}
15+
# Wrap long non-sytax highlighted code blocks
16+
- \usepackage{listings}
17+
- \let\verbatim\undefined
18+
- \let\verbatimend\undefined
19+
- \lstnewenvironment{verbatim}{\lstset{breaklines,basicstyle=\ttfamily}}{}
20+
subparagraph: yes
21+
---

wolfSSL-Porting/mkdocs.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
site_name: wolfSSL Porting Guide
2+
site_url: https://wolfssl.com/
3+
docs_dir: build/html/
4+
site_dir: html/
5+
copyright: Copyright © 2023 wolfSSL Inc.
6+
nav:
7+
- "1. Introduction": index.md
8+
- "2. Porting wolfSSL": section02.md
9+
- "3. Next Steps": section03.md
10+
- "4. Support": section04.md
11+
theme:
12+
name: null
13+
custom_dir: ../mkdocs-material/material
14+
language: en
15+
palette:
16+
primary: indigo
17+
accent: indigo
18+
font:
19+
text: roboto
20+
code: roboto mono
21+
icon: "logo.png"
22+
logo: logo.png
23+
favicon: logo.png
24+
feature:
25+
tabs: true
26+
extra_css: [skin.css]
27+
use_directory_urls: false

wolfSSL-Porting/src/section01.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Introduction
2+
3+
This guide provides a reference for developers and engineers porting the
4+
wolfSSL lightweight SSL/TLS library to new embedded platforms, operating
5+
systems, or transport mediums (TCP/IP, bluetooth, etc). It calls out
6+
areas in the wolfSSL codebase which typically require modification when
7+
porting wolfSSL. It should be considered a guide and as such, it is an
8+
evolving work. If there is something you find missing, please let us
9+
know and we’ll be happy to add instructions or clarification to the
10+
document.
11+
12+
## Audience
13+
14+
This guide caters to developers or engineers porting the wolfSSL and
15+
wolfCrypt to new platforms or environments that are not supported by
16+
default.
17+
18+
## Overview
19+
20+
Several steps need to be iterated through when getting wolfSSL to run on
21+
an embedded platform. Some of these steps are outlined in Section 2.4
22+
of the wolfSSL Manual.
23+
24+
Apart from steps in Chapter 2 of the wolfSSL Manual, there are areas in
25+
the code which may need porting or modifications in order to accommodate
26+
a specific platform. wolfSSL abstracts many of these areas, attempting
27+
to make it as easy as possible to port wolfSSL to a new platform.
28+
29+
In the ./wolfssl/wolfcrypt/settings.h file, there are several defines
30+
specific to different operating systems, TCP/IP stacks, and chipsets
31+
(ie: MBED, FREESCALE\_MQX, MICROCHIP\_PIC32, MICRIUM, EBSNET, etc).
32+
There are two main locations to put \#defines when compiling and porting
33+
wolfSSL to a new platform:
34+
35+
First, new defines for a Operating System or TCP/IP stack port are
36+
typically added to the settings.h file when a new port of wolfSSL is
37+
completed. This provides an easy way to turn on/off features as well as
38+
customize build settings that should be default for that build. New
39+
custom defines can be added in this file when doing a port of wolfSSL to
40+
a new platform. We encourage users to contribute ports of wolfSSL back
41+
to the master open source code branch on GitHub. This helps keep wolfSSL
42+
up to date and allows different ports to remain updated as the wolfSSL
43+
project improves and moves forward.
44+
45+
For users not wanting to contribute back their changes to wolfSSL
46+
proper, or for users who want to customize the wolfSSL build with
47+
additional preprocessor defines, wolfSSL recommends the use of a
48+
custom "user\_settings.h" header file. If WOLFSSL\_USER\_SETTINGS is
49+
defined when compiling the wolfSSL source files, wolfSSL will
50+
automatically include a custom header file called "user\_settings.h".
51+
This header should be created by the user and placed on the include
52+
path. This allows users to maintain one single file for their wolfSSL
53+
build, and makes it much easier to update to newer versions of wolfSSL.
54+
55+
wolfSSL encourages the submission of patches and code changes through either
56+
direct email ([email protected]), or through GitHub pull request.

wolfSSL-Porting/src/section02.md

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
# Porting wolfSSL
2+
3+
## Data Types
4+
5+
Q: When do I need to read this section?
6+
A: Setting the correct data type size for your platform is always important.
7+
8+
wolfSSL benefits speed-wise from having a 64-bit type available. Define SIZEOF_LONG and SIZEOF_LONG_LONG to match the result of sizeof(long) and sizeof(long long) on your platform. This can be added to a custom define in the settings.h file or to user_settings.h. For example, in settings.h under a sample define of MY_NEW_PLATFORM:
9+
10+
```
11+
#ifdef MY_NEW_PLATFORM
12+
#define SIZEOF_LONG 4
13+
#define SIZEOF_LONG_LONG 8
14+
...
15+
#endif
16+
```
17+
18+
There are two additional data types used by wolfSSL and wolfCrypt, called “word32” and “word16”. The default type mappings for these are:
19+
20+
```
21+
#ifndef WOLFSSL_TYPES
22+
#ifndef byte
23+
typedef unsigned char byte;
24+
#endif
25+
typedef unsigned short word16;
26+
typedef unsigned int word32;
27+
typedef byte word24[3];
28+
#endif
29+
```
30+
31+
“word32” should be mapped to the compiler’s 32-bit type, and “word16” to the compiler’s 16-bit type. If these default mappings are incorrect for your platform, you should define WOLFSSL_TYPES in settings.h or user_settings.h and assign your own custom typedefs for word32 and word16.
32+
33+
The fastmath library in wolfSSL uses the “fp_digit” and “fp_word” types. By default these are mapped in <wolfssl/wolfcrypt/tfm.h> depending on build configuration.
34+
35+
“fp_word” should be twice the size of “fp_digit”. If the default cases do not hold true for your platform, you should define WOLFSSL_BIGINT_TYPES in settings.h or user_settings.h and assign your own custom typedefs for fp_word and fp_digit.
36+
37+
wolfSSL does use a 64-bit type when available for some operations. The wolfSSL build tries to detect and set up the correct underlying data type for word64 based on what SIZEOF_LONG and SIZEOF_LONG_LONG have been set to. On some platforms that don’t have a true 64-bit type, where two 32-bit types are used in conjunction, performance can be slow. To compile out the use of 64-bit types, define NO_64BIT.
38+
39+
## Endianness
40+
41+
Q: When do I need to read this section?
42+
A: Your platform is a big endian system.
43+
44+
Is your platform big endian or little endian? wolfSSL defaults to a little endian system. If your system is big endian, define BIG_ENDIAN_ORDER when building wolfSSL. Example of setting this in settings.h:
45+
46+
```
47+
#ifdef MY_NEW_PLATFORM
48+
...
49+
#define BIG_ENDIAN_ORDER
50+
...
51+
#endif
52+
```
53+
54+
## writev
55+
56+
Q: When do I need to read this section?
57+
A: <sys/uio.h> is not available.
58+
59+
By default, the wolfSSL API makes available wolfSSL_writev() to applications, which simulates writev() semantics. On systems that don’t have the <sys/uio.h> header available, define NO_WRITEV to exclude this feature.
60+
61+
## Input/Output
62+
63+
Q: When do I need to read this section?
64+
A: A BSD-style socket API is not available, you are using a custom transport layer or TCP/IP stack, or only want to use static buffers.
65+
66+
wolfSSL defaults to using a BSD-style socket interface. If your transport layer provides a BSD socket interface, wolfSSL should integrate into it as-is, unless custom headers are needed.
67+
68+
wolfSSL provides a custom I/O abstraction layer which allows users to tailor wolfSSL's I/O functionality to their system. Full details can be found in Section 5.1.2 of the wolfSSL Manual:
69+
https://wolfssl.com/wolfSSL/Docs-wolfssl-manual-5-portability.html
70+
71+
Simply put, you can define WOLFSSL_USER_IO, then write your own I/O callback functions using wolfSSL's default EmbedSend() and EmbedReceive() as templates. These two functions are located in ./src/wolfio.c.
72+
73+
wolfSSL uses dynamic buffers for input and output, which default to 0 bytes. If an input record is received that is greater in size than the buffer, then a dynamic buffer is temporarily used to handle the request and then freed.
74+
75+
If you prefer using large, 16kB static buffers which will never need dynamic memory, you can enable this option by defining LARGE_STATIC_BUFFERS.
76+
77+
If dynamic buffers are used and the user requests an wolfSSL_write() that is bigger than the buffer size, then a dynamic block up to MAX_RECORD_SIZE is used to send the data. Users wishing to only send the data in chunks of the current buffer size at maximum, as defined by RECORD_SIZE, can do this by defining STATIC_CHUNKS_ONLY. When using this define, RECORD_SIZE defaults to 128 bytes.
78+
79+
## Filesystem
80+
81+
Q: When do I need to read this section?
82+
A: No file system is available, standard file system functions are not available, or you have a custom file system.
83+
84+
wolfSSL uses the filesystem for loading keys and certificates into the SSL session or context. wolfSSL also allows loading these from memory buffers. If strictly using memory buffers, a filesystem is not needed.
85+
86+
You can disable wolfSSL's usage of the filesystem by defining NO_FILESYSTEM when building the library. This means that certificates and keys will need to be loaded from memory buffers instead of files. An example of setting this in settings.h:
87+
88+
```
89+
#ifdef MY_NEW_PLATFORM
90+
...
91+
#define NO_FILESYSTEM
92+
...
93+
#endif
94+
```
95+
96+
Test key and certificate buffers can be found in the ./wolfssl/certs_test.h header file. These will match up to corresponding certificates and keys found in the ./certs directory.
97+
98+
The certs_test.h header file can be updated using the ./gencertbuf.pl script if needed. Inside gencertbuf.pl, there are two arrays: fileList_1024 and fileList_2048. Additional certificates or keys may be added to the respective array, depending on key size, and must be in DER format. The above mentioned arrays map a certificate/key file location with the desired buffer name. After modifying gencertbuf.pl, running it from the wolfSSL root directory will update the certificate and key buffers in ./wolfssl/certs_test.h:
99+
100+
./gencertbuf.pl
101+
102+
If you would like to use a filesystem other than the default, the filesystem abstraction layer is located in ./wolfssl/wolfcrypt/wc_port.h. Here you will see filesystem ports for various platforms including EBSNET, FREESCALE_MQX, and MICRIUM. You can add a custom define for your platform if needed - allowing you to define file system functions with XFILE, XFOPEN, XFSEEK, etc. For example, the filesystem layer in wc_port.h for Micrium's µC/OS (MICRIUM) is as follows:
103+
104+
```
105+
#elif defined(MICRIUM)
106+
#include <fs.h>
107+
#define XFILE FS_FILE*
108+
#define XFOPEN fs_fopen
109+
#define XFSEEK fs_fseek
110+
#define XFTELL fs_ftell
111+
#define XREWIND fs_rewind
112+
#define XFREAD fs_fread
113+
#define XFCLOSE fs_fclose
114+
#define XSEEK_END FS_SEEK_END
115+
#define XBADFILE NULL
116+
```
117+
118+
## Threading
119+
120+
Q: When do I need to read this section?
121+
A: You want to use wolfSSL in a multithreaded environment, or want to just compile it in single threaded mode.
122+
123+
If wolfSSL will only be used in a single threaded environment, the wolfSSL mutex layer can be disabled when compiling wolfSSL by defining SINGLE_THREADED. This will negate the need to port the wolfSSL mutex layer.
124+
125+
If wolfSSL needs to be used in a multithreaded environment, the wolfSSL mutex layer will need to be ported to the new environment. The mutex layer can be found in ./wolfssl/wolfcrypt/wc_port.h and ./wolfcrypt/src/wc_port.c. wolfSSL_Mutex will need to be defined for the new system in wc_port.h and the mutex functions (wc_InitMutex, wc_FreeMutex, wc_LockMutex and wc_UnLockMutex) in wc_port.c. You can search in wc_port.h and wc_port.c to see an example for some existing platform port layers (EBSNET, FREESCALE_MQX, etc.).
126+
127+
## Random Seed
128+
129+
Q: When do I need to read this section?
130+
A: Either /dev/random or /dev/urandom is not available or you want to integrate into a hardware RNG.
131+
132+
By default, wolfSSL uses /dev/urandom or /dev/random to generate a RNG seed. The NO_DEV_RANDOM define can be used when building wolfSSL to disable the default GenerateSeed() function. If this is defined, you need to write a custom GenerateSeed() function in ./wolfcrypt/src/random.c, specific to your target platform. This allows you to seed wolfSSL’s PRNG with a hardware-based random entropy source if available.
133+
134+
For examples of how GenerateSeed() needs to be written, reference wolfSSL’s existing GenerateSeed() implementations in ./wolfcrypt/src/random.c.
135+
136+
## Memory
137+
138+
Q: When do I need to read this section?
139+
A: When you don’t have standard memory functions available or are interested in memory usage differences between optional math libraries.
140+
141+
wolfSSL proper uses both malloc() and free() by default. When using the normal big integer math library, wolfCrypt will also use realloc().
142+
143+
By default wolfSSL/wolfCrypt use the normal big integer math library, which uses quite a bit of dynamic memory. When building wolfSSL, the fastmath library can be enabled, which is both faster and uses no dynamic memory for crypto operations (all on the stack). By using fastmath, wolfSSL won't need a realloc() implementation at all. As the SSL layer of wolfSSL still uses some dynamic memory, malloc() and free() are still required.
144+
145+
For a comparison of resource usage (stack/heap) between the big integer math library and fastmath library, ask us to see our Resource Use document.
146+
147+
To enable fastmath, define USE_FAST_MATH and build in ./wolfcrypt/src/tfm.c instead of ./wolfcrypt/src/integer.c. Since the stack memory can be large when using fastmath, we recommend defining TFM_TIMING_RESISTANT as well.
148+
149+
If the normal malloc(), free(), and possibly realloc() functions are not available, define XMALLOC_USER, then provide custom memory function hooks in ./wolfssl/wolfcrypt/types.h specific to the target environment.
150+
151+
Please read section 5.1.1.1 of the wolfSSL Manual for details about using XMALLOC_USER:
152+
https://wolfssl.com/wolfSSL/Docs-wolfssl-manual-5-portability.html
153+
154+
## Time
155+
156+
Q: When do I need to read this section?
157+
A: When standard time functions (time(), gmtime()) are not available, or you need to specify a custom clock tick function.
158+
159+
By default, wolfSSL uses time(), gmtime(), and ValidateDate(), as specified in ./wolfcrypt/src/asn.c. These are abstracted to XTIME, XGMTIME, and XVALIDATE_DATE. If the standard time functions, and time.h, are not available, the user can define USER_TIME. After defining USER_TIME, the user can define their own XTIME, XGMTIME, and XVALIDATE_DATE functions.
160+
161+
wolfSSL uses time(0) by default for the clock tick function. This is located in ./src/internal.c inside of the LowResTimer() function.
162+
163+
Defining USER_TICKS allows the user to define their own clock tick function if time(0) is not wanted. The custom function needs second accuracy, but doesn’t have to be correlated to EPOCH. See LowResTimer() function in ./src/internal.c for reference.
164+
165+
## C Standard Library
166+
167+
Q: When do I need to read this section?
168+
A: When you don’t have a C standard library available, or have a custom one.
169+
170+
wolfSSL can be built without the C standard library to provide a higher level of portability and flexibility to developers. When doing so, the user needs to map functions they wish to use instead of the C standard ones.
171+
172+
Section 2.8, above, covered memory functions. In addition to memory function abstraction, wolfSSL also abstracts string function and math functions, where the specific functions are typically abstracted to a define in the form of X<FUNC>, where <FUNC> is the name of the function being abstracted.
173+
174+
Please read Section 5.1 of the wolfSSL Manual for details:
175+
https://www.wolfssl.com/wolfSSL/Docs-wolfssl-manual-5-portability.html
176+
177+
## Logging
178+
179+
Q: When do I need to read this section?
180+
A: You want to enable debug messages but don’t have stderr available.
181+
182+
By default, wolfSSL provides debug output through stderr. In order for debug messages to be enabled, wolfSSL must be compiled with DEBUG_WOLFSSL defined, and wolfSSL_Debugging_ON() must be called from the application code. wolfSSL_Debugging_OFF() may be used by the application layer to turn off wolfSSL debug messages.
183+
184+
For environments which do not have stderr available, or wish to output debug messages over a different output stream or in a different format, wolfSSL allows applications to register a logging callback.
185+
186+
Please read Section 8.1 of the wolfSSL Manual for details:
187+
https://www.wolfssl.com/wolfSSL/Docs-wolfssl-manual-8-debugging.html
188+
189+
## Public Key Operations
190+
191+
Q: When do I need to read this section?
192+
A: You want to use your own public key implementation with wolfSSL.
193+
194+
wolfSSL allows users to write their own public key callbacks which will be called when the SSL/TLS layer needs to do public key operations. The user can optionally define 6 functions:
195+
196+
ECC sign callback
197+
ECC verify callback
198+
RSA sign callback
199+
RSA verify callback
200+
RSA encrypt callback
201+
RSA decrypt callback
202+
203+
For full details, please read Section 6.4 of the wolfSSL Manual:
204+
https://www.wolfssl.com/wolfSSL/Docs-wolfssl-manual-6-callbacks.html
205+
206+
## Atomic Record Layer Processing
207+
208+
Q: When do I need to read this section?
209+
A: You want to do your own processing of record layers, specifically MAC/encrypt and decrypt/verify operations.
210+
211+
By default, wolfSSL handles record layer processing for the user using its cryptography library, wolfCrypt. wolfSSL provides Atomic Record Processing callbacks for users who wish to have more control over MAC/encrypt and decrypt/verify functionality during the SSL/TLS connection.
212+
213+
The user will need to define 2 functions:
214+
MAC/encrypt callback function
215+
Decrypt/verify callback function
216+
217+
For full details, please read Section 6.3 of the wolfSSL Manual:
218+
https://www.wolfssl.com/wolfSSL/Docs-wolfssl-manual-6-callbacks.html
219+
220+
## Features
221+
222+
Q: When do I need to read this section?
223+
A: When you want to disable features.
224+
225+
Features can be disabled when building wolfSSL by using the appropriate defines. For a list of defines available, please refer to Chapter 2 of the wolfSSL Manual:
226+
https://www.wolfssl.com/wolfSSL/Docs-wolfssl-manual-2-building-wolfssl.html

0 commit comments

Comments
 (0)