Wolfssl [version 0.0.2; documenting]

I think that the STM32F2 is more on target as this is the exact controller family the Photon and Electron use - but it’s true these are also ARM contollers, so that would be the more general approach.

Sounds good. We can see what @jenschr comes up with going down that path. I did manage to get a binary, but there is a little bit to do before testing.

    ../../src/wolfssl/wolfcrypt/port/ti/ti-ccm.h
    ../../src/wolfssl/wolfcrypt/port/ti/ti-hash.h
attempting to compile firmware 
downloading binary from: /v1/binaries/5954a4d660716d4cb03e7dc2
saving to: photon_firmware_1498719343508.bin
Memory use: 
   text	   data	    bss	    dec	    hex	filename
 108620	    124	   5868	 114612	  1bfb4	/workspace/target/workspace.elf

Compile succeeded.
Saved firmware to: /Users/cermak/Software/particle/libraries/wolfssl/examples/wolfssl_client/photon_firmware_1498719343508.bin

Not much space to play with.

Is there a way we can get an object dump of symbols from the cloud? Tracking down these are painful:

/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-gettimeofdayr.o): In function `_gettimeofday_r':
gettimeofdayr.c:(.text._gettimeofday_r+0xe): undefined reference to `_gettimeofday'

Git repo updated. The wolfssl library works pretty much out of the box.

saving to: photon_firmware_1498757287624.bin
Memory use: 
   text	   data	    bss	    dec	    hex	filename
 109148	    124	   6280	 115552	  1c360	/workspace/target/workspace.elf

I had to make a slight adjustment to the example. We have to wait a little bit for a server response or it gets skipped. You have to send a valid msg to get a response.

RobPro:wolfssl_client cermak$ particle serial monitor --follow
Polling for available serial device...
Opening serial monitor for com port: "/dev/cu.usbmodem1421"
Serial monitor opened successfully:
Connected to jupyter.lccllc.info
SSL version is TLSv1.2
SSL cipher suite is TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
client.available():128
Server response: HTTP/1.1 200 OK
Date: Thu, 29 Jun 2017 17:29:59 GMT
Server: Apache/2.4.16 (Fedora) OpenSSL/1.0.1k-fips mod_fcgid/2.3.9 PHP/5.6.15
Last-Modified: Fri, 12 Feb 2016 21:19:21 GMT
ETag: "14e5-52b99387f5588"
Accept-Ranges: bytes
Content-Length: 5349
Content-Type: text/html; charset=UTF-8

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    <title>lccllc.info</title>

Cipher suite reported in use matches the one reported by the server. Looks good.

[29/Jun/2017:17:29:59 +0000] 166.176.187.3 TLSv1.2 DHE-RSA-AES256-SHA256 "GET / HTTP/1.1" 5349

4 Likes

Oh my. I had to take a break from this for a couple days and you already got it working? That was much faster than I would have managed :blush:

Looking at the memory output, I guess the next would be trying to slim this down a bit? The 115552 reported would not leave too much for anything else, but I’m sure that server/client keys is quite a bit of the “text” in memory? On a Photon, some of that could maybe be offloaded to the EEPROM portion of the memory and on a P1 there’s lots of space given the 1Mb extra Flash.

The ATECC508A will also hold this part, so I’m curious to see how much memory that would save. I won’t be back on this project until Monday, but I’ve already made dev cards with a P1 module and a ATECC508A. I presume you have a similar need for TLS that I have, so if you’d be interested one of these dev boards @cermak, I don’t mind sharing it. Just PM me your address and I’ll ship it right away.

With additional testing I can make this library available on the web ide. I’ll clean up documentation along the way. I don’t want to post this right away as it has a fair number of pieces. Comments and suggestions welcome.

At the same time, I’ll clone the wolfssl repo and send them a pull request so future porting efforts are minimized.

The first porting effort isn’t always the best.

The wolfssl part is working great for now, so I’ve worked on getting wolfmqtt to play along with it so that I can get:

  1. Plain MQTT
  2. Amazon IoT

up and running. I have cloned @cermak’s repo and added my lib there https://github.com/jenschr/particle/tree/master/libraries/wolfmqtt After a lot of back and forth I have a working porting script as well as something that “almost” compiles. I’ve resolved all the “normal” compile errors for the example, but I’m having a hard time understanding this error from CLI when compiling for the Photon:

Building target: target/workspace.elf
Invoking: ARM GCC C++ Linker
mkdir -p target/
arm-none-eabi-g++ -DSTM32_DEVICE -DSTM32F2XX -DPLATFORM_THREADING=1 -DPLATFORM_ID=6 -DPLATFORM_NAME=photon -DUSBD_VID_SPARK=0x2B04 -DUSBD_PID_DFU=0xD006 -DUSBD_PID_CDC=0xC006 -g3 -gdwarf-2 -Os -mcpu=cortex-m3 -mthumb -DINCLUDE_PLATFORM=1 -fno-builtin -DUSE_STDPERIPH_DRIVER -DDFU_BUILD_ENABLE -DSYSTEM_VERSION_STRING=0.6.2 -DRELEASE_BUILD -Werror -I./inc -I../../../user/inc -I../../../dynalib/inc -I../../../services/inc -I../../../hal/inc -I../../../hal/shared -I../../../hal/src/photon -I../../../hal/src/stm32f2xx -I../../../hal/src/stm32 -I../../../hal/src/photon/api -I../../../system/inc -I../../../rt-dynalib/inc -I../../../wiring/inc -I../../../modules/photon/system-part1/inc -I../../../modules/shared/stm32f2xx/inc -I../../../platform/shared/inc -I../../../platform/MCU/STM32F2xx/STM32_USB_Host_Driver/inc -I../../../platform/MCU/STM32F2xx/STM32_StdPeriph_Driver/inc -I../../../platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc -I../../../platform/MCU/STM32F2xx/STM32_USB_Device_Driver/inc -I../../../platform/MCU/STM32F2xx/SPARK_Firmware_Driver/inc -I../../../platform/MCU/shared/STM32/inc -I../../../platform/MCU/STM32F2xx/CMSIS/Include -I../../../platform/MCU/STM32F2xx/CMSIS/Device/ST/Include -I. -MD -MP -MF target/workspace.elf.d -ffunction-sections -fdata-sections -Wall -Wno-switch -Wno-error=deprecated-declarations -fmessage-length=0 -fno-strict-aliasing -DSPARK=1 -DPARTICLE=1 -DSTART_DFU_FLASHER_SERIAL_SPEED=14400 -DSTART_YMODEM_FLASHER_SERIAL_SPEED=28800 -fno-builtin-malloc -fno-builtin-free -fno-builtin-realloc -DUSER_FIRMWARE_IMAGE_SIZE=0x20000 -DUSER_FIRMWARE_IMAGE_LOCATION=0x80A0000 -DMODULAR_FIRMWARE=1 -DMODULE_VERSION=4 -DMODULE_FUNCTION=5 -DMODULE_INDEX=1 -DMODULE_DEPENDENCY=4,2,108 -D_WINSOCK_H -D_GNU_SOURCE target//obj/src/user_module.o target//obj/src/module_info.o target//obj/src/user_export.o target//obj/src/newlib_stubs.o  --output target/workspace.elf -Wl,--whole-archive ../../../hal/src/photon/lib/STM32F2xx_Peripheral_Libraries.a -Wl,--no-whole-archive -nostartfiles -Xlinker --gc-sections -L../../../build/arm/linker/stm32f2xx  -L../../../build/target/user/platform-6-m -L../../../build/target/services-dynalib/arm/ -L../../../build/target/hal-dynalib/platform-6-m/ -L../../../build/target/system-dynalib/platform-6-m/ -L../../../build/target/rt-dynalib/platform-6-m/ -L../../../build/target/wiring/platform-6-m/ -L../../../build/target/communication-dynalib/platform-6-m/ -L../../../build/target/platform/platform-6-m/ -L../../../build/target/wiring_globals/platform-6-m/ -L../../../hal/src/photon/lib/ -L../../../build/arm/linker -Wl,--whole-archive -luser -lhal-dynalib -lservices-dynalib -lsystem-dynalib -lrt-dynalib -lwiring -lcommunication-dynalib -lplatform -lwiring_globals -Wl,--no-whole-archive -lnosys --specs=nano.specs -L../../../modules/photon/system-part2 -L../../../modules/photon/system-part1 -L. -T./linker.ld -Wl,--defsym,USER_FIRMWARE_IMAGE_SIZE=0x20000 -Wl,--defsym,USER_FIRMWARE_IMAGE_LOCATION=0x80A0000 -Wl,-Map,target/workspace.map
/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x10): undefined reference to `_write'
/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0xc): undefined reference to `_close'
/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0xe): undefined reference to `_fstat'
/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty'
/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x10): undefined reference to `_lseek'
/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x10): undefined reference to `_read'
collect2: error: ld returned 1 exit status
../../../build/module.mk:222: recipe for target 'target/workspace.elf' failed
make[1]: Leaving directory '/firmware/modules/photon/user-part'
make[1]: *** [target/workspace.elf] Error 1
../build/recurse.mk:11: recipe for target 'modules/photon/user-part' failed
make: *** [modules/photon/user-part] Error 2

From what I’ve seen for similar errors on the forum, I’ve seen @bko mention that this may have to do with “unistd.h”. I’ve gone through the source and this file is not included. Does anyone have any pointers as to what this error may stem from?

There is a define to try as this looks like std I/O. #define WOLFMQTT_NO_STDIO and see if that helps.

We may need to deal with all the remaining printf statements in the ino example.

1 Like

So the define didn’t help, but changing printf to sprintf did the trick! Now it compiles and runs, but it does not connect. That’s quite a big jump forward! Will keep working on this later tonight. Thanks Rob! :slight_smile:

Those symbol errors are nefarious. Not a lot of information on where they might be originating. I am thinking if we got an object/symbol dump for each object file, these could be found more easily. I may send a feature request later.

I’ll have a chance in the next day or so to take a look. I’ll merge the PR and try.

So, I merged the PR. I had to move some files around to actually compile the mqtt library with the ssl library. There is a build script in the example directory. You will need to edit it a bit to match what your compiling for.

mkbin:
  -b compile the binary in the cloud
  -f if compile is successful, flash via DFU-UTIL
  -s if compile successful, flash via serial if used with -f
  -m if compile successful, after attempting to flash, will
       automatically drop you into serial monitor mode with --follow

If compile fails, errors are stashed to err.txt.

So, I don’t think you were pulling in all the code which is why it looks like it succeeded and did not connect. There are more symbol errors to navigate unfortunately.

/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x10): undefined reference to `_write'
/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0xc): undefined reference to `_close'
/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0xe): undefined reference to `_fstat'
/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty'
/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x10): undefined reference to `_lseek'
/usr/local/gcc-arm-embedded/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m/libg_s.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x10): undefined reference to `_read'
collect2: error: ld returned 1 exit status
../../../build/module.mk:222: recipe for target 'target/workspace.elf' failed
make[1]: *** [target/workspace.elf] Error 1
make[1]: Leaving directory '/firmware/modules/photon/user-part'
../build/recurse.mk:11: recipe for target 'modules/photon/user-part' failed
make: *** [modules/photon/user-part] Error 2
Compile failed.  Errors captured in err.txt.

More later…

Finally got a little bit of time to move a little further on this. I finally have a working example of AWS IoT to verify that when we get the wolfmqtt working that things are really working. Not only do we have to get the client working, we have to encode the client certificates.

wolfmqtt

  • Create a SSL context with RootCA, Client Cert & Priv Cert from AWS IoT
  • Use the SSL context to connect to AWS IoT and perform the requested work

I am using a combination of python from a hackster.io project and curl so I can get a handle on what wolfssl/wolfmqtt need to do to initiate a payload to AWS IoT.

Here is the hackster link. This uses “Python and Paho for MQTT with AWS IoT”.

Now on to completing the wolfmqtt port and seeing if we can get data back.

The payload can be anything, but I used an example from the AWS documentation. I am using a different thingy. The naming is up to you.

curl --tlsv1.2 --cacert ./aws-iot-rootCA.crt --cert ./cert.pem --key ./privkey.pem\
  -X POST -d "{ \"serialNumber\": \"G030JF053216F1BS\", \"clickType\": \"SINGLE\", \"batteryVoltage\": \"2000mV\" }" "https://data.iot.us-west-2.amazonaws.com:8443/topics/temperatureA?qos=1"

If all goes well, the receiver gets a payload:

[cermak@localhost python-paho-mqtt-for-aws-iot]$ python awsiotsub.py 
Connection returned result: 0
topic: temperatureA
payload: { "serialNumber": "G030JF053216F1BS", "clickType": "SINGLE", "batteryVoltage": "2000mV" }

I haven’t figure out how to view this payload on AWS IoT, but I can at least see the packet via CloudWatch.

2017-07-15 02:06:30.857 TRACEID:8afa0c4b-6390-cdee-1002-c90d55a4d09d PRINCIPALID:752497542b54204429ce0b82a081b83e8603828e44689547ab73ceef3a0a83f7 [INFO] EVENT:PublishEvent TOPICNAME:temperatureA MESSAGE:PublishIn Status: SUCCESS
2017-07-15 02:06:30.857 TRACEID:8afa0c4b-6390-cdee-1002-c90d55a4d09d PRINCIPALID:752497542b54204429ce0b82a081b83e8603828e44689547ab73ceef3a0a83f7 [INFO] EVENT:PublishEvent MESSAGE: IpAddress: 216.115.122.132 SourcePort: 39856
1 Like

I am in a compiler bind. Any helpful hints? Any way out? I have also switched to performing a local build on the mac.

The offending header file is ssl.h via the wolfssl library. Using the wolfssl library on its own works with the “application.h” in ssl.h, but not when both libraries are built together. My last resort is just to manually define it in the header file. I don’t like stubbing things like that.

If I do not include an #include "application.h", I see this error:

mkdir -p ../build/target/user/platform-6-m/wolfmqtt/src/
arm-none-eabi-gcc -DSTM32_DEVICE -DSTM32F2XX -DPLATFORM_THREADING=1 -DPLATFORM_ID=6 -DPLATFORM_NAME=photon -DUSBD_VID_SPARK=0x2B04 -DUSBD_PID_DFU=0xD006 -DUSBD_PID_CDC=0xC006 -DSPARK_PLATFORM -g3 -gdwarf-2 -Os -mcpu=cortex-m3 -mthumb -DINCLUDE_PLATFORM=1 -DPRODUCT_ID=6 -DPRODUCT_FIRMWARE_VERSION=65535 -DUSE_STDPERIPH_DRIVER -DDFU_BUILD_ENABLE -DSYSTEM_VERSION_STRING=0.6.2 -DRELEASE_BUILD -I./inc -I../wiring/inc -I../system/inc -I../services/inc -I../communication/src -I../hal/inc -I../hal/shared -I../hal/src/photon -I../hal/src/stm32f2xx -I../hal/src/stm32 -I../hal/src/photon/api -I../platform/shared/inc -I../platform/MCU/STM32F2xx/CMSIS/Include -I../platform/MCU/STM32F2xx/CMSIS/Device/ST/Include -I../platform/MCU/STM32F2xx/SPARK_Firmware_Driver/inc -I../platform/MCU/shared/STM32/inc -I../platform/MCU/STM32F2xx/STM32_StdPeriph_Driver/inc -I../platform/MCU/STM32F2xx/STM32_USB_Device_Driver/inc -I../platform/MCU/STM32F2xx/STM32_USB_Host_Driver/inc -I../platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc -I../dynalib/inc -I/Users/cermak/Documents/src/wolfmqtt/ -I/Users/cermak/Documents/src/wolfmqtt/inc -I./libraries -I/Users/cermak/Documents/src/wolfmqtt/ -I/Users/cermak/Documents/src/wolfmqtt/ -I/Users/cermak/Documents/src/wolfmqtt/ -I/Users/cermak/Documents/src/wolfmqtt/ -I. -MD -MP -MF ../build/target/user/platform-6-m/wolfmqtt/src/mqttclient.o.d -ffunction-sections -fdata-sections -Wall -Wno-switch -Wno-error=deprecated-declarations -fmessage-length=0 -fno-strict-aliasing -DSPARK=1 -DPARTICLE=1 -DSTART_DFU_FLASHER_SERIAL_SPEED=14400 -DSTART_YMODEM_FLASHER_SERIAL_SPEED=28800 -DSPARK_PLATFORM_NET=BCM9WCDUSI09 -fno-builtin-malloc -fno-builtin-free -fno-builtin-realloc  -DLOG_INCLUDE_SOURCE_INFO=1 -DPARTICLE_USER_MODULE -DUSE_THREADING=0 -DUSE_THREADING=0 -DUSE_SPI=SPI -DUSE_CS=A2 -DUSE_SPI=SPI -DUSE_CS=A2 -DUSER_FIRMWARE_IMAGE_SIZE=0x20000 -DUSER_FIRMWARE_IMAGE_LOCATION=0x80A0000 -DMODULAR_FIRMWARE=1 -DMODULE_VERSION=4 -DMODULE_FUNCTION=5 -DMODULE_INDEX=1 -DMODULE_DEPENDENCY=4,2,108 -D_WINSOCK_H -D_GNU_SOURCE -DLOG_MODULE_CATEGORY="\"app\""  -fno-exceptions -fno-rtti -fcheck-new -std=gnu++11 -c -o ../build/target/user/platform-6-m/wolfmqtt/src/mqttclient.o /Users/cermak/Documents/src/wolfmqtt/src/mqttclient.cpp
In file included from /Users/cermak/Documents/src/wolfmqtt/src/mqttclient.cpp:7:0:
/Users/cermak/Documents/src/wolfmqtt/inc/wolfssl/ssl.h:2329:13: error: 'size_t' does not name a type
 WOLFSSL_API size_t SSL_get_finished(const WOLFSSL *s, void *buf, size_t count);
             ^
/Users/cermak/Documents/src/wolfmqtt/inc/wolfssl/ssl.h:2330:13: error: 'size_t' does not name a type
 WOLFSSL_API size_t SSL_get_peer_finished(const WOLFSSL *s, void *buf, size_t count);
             ^

If I include the #include "application.h", I see this error:

mkdir -p ../build/target/user/platform-6-m/wolfmqtt/src/
arm-none-eabi-gcc -DSTM32_DEVICE -DSTM32F2XX -DPLATFORM_THREADING=1 -DPLATFORM_ID=6 -DPLATFORM_NAME=photon -DUSBD_VID_SPARK=0x2B04 -DUSBD_PID_DFU=0xD006 -DUSBD_PID_
CDC=0xC006 -DSPARK_PLATFORM -g3 -gdwarf-2 -Os -mcpu=cortex-m3 -mthumb -DINCLUDE_PLATFORM=1 -DPRODUCT_ID=6 -DPRODUCT_FIRMWARE_VERSION=65535 -DUSE_STDPERIPH_DRIVER -D
DFU_BUILD_ENABLE -DSYSTEM_VERSION_STRING=0.6.2 -DRELEASE_BUILD -I./inc -I../wiring/inc -I../system/inc -I../services/inc -I../communication/src -I../hal/inc -I../hal/shared -I../hal/src/photon -I../hal/src/stm32f2xx -I../hal/src/stm32 -I../hal/src/photon/api -I../platform/shared/inc -I../platform/MCU/STM32F2xx/CMSIS/Include -I../platform/MCU/STM32F2xx/CMSIS/Device/ST/Include -I../platform/MCU/STM32F2xx/SPARK_Firmware_Driver/inc -I../platform/MCU/shared/STM32/inc -I../platform/MCU/STM32F2xx/STM32_StdPeriph_Driver/inc -I../platform/MCU/STM32F2xx/STM32_USB_Device_Driver/inc -I../platform/MCU/STM32F2xx/STM32_USB_Host_Driver/inc -I../platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc -I../dynalib/inc -I/Users/cermak/Documents/src/wolfmqtt/ -I/Users/cermak/Documents/src/wolfmqtt/inc -I./libraries -I/Users/cermak/Documents/src/wolfmqtt/ -I/Users/cermak/Documents/src/wolfmqtt/ -I/Users/cermak/Documents/src/wolfmqtt/ -I/Users/cermak/Documents/src/wolfmqtt/ -I. -MD -MP -MF ../build/target/user/platform-6-m/wolfmqtt/src/internal.o.d -ffunction-sections -fdata-sections -Wall -Wno-switch -Wno-error=deprecated-declarations -fmessage-length=0 -fno-strict-aliasing -DSPARK=1 -DPARTICLE=1 -DSTART_DFU_FLASHER_SERIAL_SPEED=14400 -DSTART_YMODEM_FLASHER_SERIAL_SPEED=28800 -DSPARK_PLATFORM_NET=BCM9WCDUSI09 -fno-builtin-malloc -fno-builtin-free -fno-builtin-realloc  -DLOG_INCLUDE_SOURCE_INFO=1 -DPARTICLE_USER_MODULE -DUSE_THREADING=0 -DUSE_THREADING=0 -DUSE_SPI=SPI -DUSE_CS=A2 -DUSE_SPI=SPI -DUSE_CS=A2 -DUSER_FIRMWARE_IMAGE_SIZE=0x20000 -DUSER_FIRMWARE_IMAGE_LOCATION=0x80A0000 -DMODULAR_FIRMWARE=1 -DMODULE_VERSION=4 -DMODULE_FUNCTION=5 -DMODULE_INDEX=1 -DMODULE_DEPENDENCY=4,2,108 -D_WINSOCK_H -D_GNU_SOURCE -DLOG_MODULE_CATEGORY="\"app\""  -fno-exceptions -fno-rtti -fcheck-new -std=gnu++11 -c -o ../build/target/user/platform-6-m/wolfmqtt/src/internal.o /Users/cermak/Documents/src/wolfmqtt/src/internal.cpp
In file included from ../services/inc/service_debug.h:34:0,
                 from ../services/inc/debug.h:1,
                 from ../wiring/inc/spark_wiring.h:36,
                 from ./inc/application.h:40,
                 from /Users/cermak/Documents/src/wolfmqtt/inc/wolfssl/ssl.h:70,
                 from /Users/cermak/Documents/src/wolfmqtt/inc/wolfssl/internal.h:29,
                 from /Users/cermak/Documents/src/wolfmqtt/src/internal.cpp:32:
../services/inc/logging.h:260:1: error: template with C linkage
 template<typename T>

Hello @cermak and @jenschr

Wondering how your efforts are coming?
Having an operational SSL Client ported over would be a great step forward.

Thanks in advance.

@jimini - It is slow going. The bare SSL client I believe is working. Adding the mqtt client (wolfmqtt) using SSL is proving problematic. What I am doing now is simply pulling mqtt items into the operational wolfssl client piecemeal to be sure things compile all along the way. The two groups of headers for wolfssl and wolfmqtt do not play nicely with the Particle headers (see prior post) – so there will be a bit of refactoring needed once I understand how all the code interacts with each other.

If you have the time to write your own mqtt library with a well understood API, then you can begin using the SSL client right away. I believe the CA, client certificate and private key can be loaded into the wolfssl client to provide the necessary handshake to AWS IoT. Once that is done, you can just work with the raw API for AWS IoT.

This is a volunteer effort for me. The effort has been slowed down substantially as I’ve been recently brought back into the workforce. As I make progress, I will be updating this post & github and the three or four posts I have going in the forum. I am pretty deep down the rabbit hole. It continues to be fun project.

The only real concern for this port is the memory footprint. The resulting firmware will only leave a small amount of space for custom code. @jenschr has a compelling hardware solution that could solve some of the space utilization. None of this does any good, if the software isn’t there.

More later as progress continues.

Edit: I’ve been working on this for so long, I almost forgot the original motivation for this project. For the greenhouse, I am pushing data to Ubidots via other means. As sooo many suggest, we can just use the Pub/Sub technology provided. I like direct means as much as possible. So, the original motivation is to get a SSL client working and improve the Ubidots library so I can push data back and forth using the API via https://things.ubidots.com.

1 Like

Thanks @cermak

Heck, even an operational SSL client would let me talk direct to my API/Lambda… is your repo runnable, and what are you using for your build tool-chain?

@jimini - The repo is setup to compile using the particle CLI.

If you clone the repo:

REPO : github.com/jr3cermak/particle/tree/master/libraries/wolfssl

Move the wolfssl directory into a working particle CLI structure. For the Mac, the typical path is ${HOME}/Particle/libraries. Move the wolfssl directory in there, cd to libraries/wolfssl and

$ particle compile photon examples/wolfssl_client/wolfssl_client.ino

Compiling code for photon

Including:
    examples/wolfssl_client/wolfssl_client.ino
    library.properties
    src/asm.cpp
    src/aes.cpp
    src/arc4.cpp
    src/async.cpp
    src/camellia.cpp
    src/asn.cpp
    src/blake2b.cpp
    src/chacha.cpp
    src/chacha20_poly1305.cpp
    src/cmac.cpp
    src/compress.cpp
    src/coding.cpp
    src/curve25519.cpp
    src/crl.cpp
    src/des3.cpp
    src/ecc.cpp
    src/dsa.cpp
    src/dh.cpp
    src/ecc_fp.cpp
    src/ed25519.cpp
    src/fe_operations.cpp
    src/error.cpp
    src/fe_low_mem.cpp
    src/ge_operations.cpp
    src/ge_low_mem.cpp
    src/hash.cpp
    src/hc128.cpp
    src/integer.cpp
    src/internal.cpp
    src/hmac.cpp
    src/idea.cpp
    src/io.cpp
    src/keys.cpp
    src/logging.cpp
    src/md2.cpp
    src/md4.cpp
    src/md5.cpp
    src/memory.cpp
    src/pkcs12.cpp
    src/misc.cpp
    src/ocsp.cpp
    src/pkcs7.cpp
    src/poly1305.cpp
    src/pwdbased.cpp
    src/random.cpp
    src/rabbit.cpp
    src/ripemd.cpp
    src/rsa.cpp
    src/sha256.cpp
    src/sha512.cpp
    src/sha.cpp
    src/sniffer.cpp
    src/signature.cpp
    src/srp.cpp
    src/ssl.cpp
    src/tfm.cpp
    src/tls.cpp
    src/wc_port.cpp
    src/wc_encrypt.cpp
    src/wolfevent.cpp
    src/wolfmath.cpp
    src/wolfssl/callbacks.h
    src/wolfcrypt/src/misc.c
    src/wolfssl/crl.h
    src/wolfssl/certs_test.h
    src/wolfssl/internal.h
    src/wolfssl/error-ssl.h
    src/wolfssl/io.h
    src/wolfssl/include.am
    src/wolfssl/ocsp.h
    src/wolfssl/options.h
    src/wolfssl/options.h.in
    src/wolfssl/sniffer.h
    src/wolfssl/sniffer_error.h
    src/wolfssl/sniffer_error.rc
    src/wolfssl/ssl.h
    src/wolfssl/version.h.in
    src/wolfssl/version.h
    src/wolfssl/test.h
    src/wolfssl/openssl/aes.h
    src/wolfssl/openssl/asn1.h
    src/wolfssl/openssl/bio.h
    src/wolfssl/openssl/bn.h
    src/wolfssl/openssl/des.h
    src/wolfssl/openssl/dh.h
    src/wolfssl/openssl/dsa.h
    src/wolfssl/openssl/ec.h
    src/wolfssl/openssl/ec25519.h
    src/wolfssl/openssl/crypto.h
    src/wolfssl/openssl/ed25519.h
    src/wolfssl/openssl/ecdh.h
    src/wolfssl/openssl/engine.h
    src/wolfssl/openssl/ecdsa.h
    src/wolfssl/openssl/hmac.h
    src/wolfssl/openssl/include.am
    src/wolfssl/openssl/evp.h
    src/wolfssl/openssl/md4.h
    src/wolfssl/openssl/md5.h
    src/wolfssl/openssl/lhash.h
    src/wolfssl/openssl/err.h
    src/wolfssl/openssl/conf.h
    src/wolfssl/openssl/ocsp.h
    src/wolfssl/openssl/opensslv.h
    src/wolfssl/openssl/pkcs12.h
    src/wolfssl/openssl/ossl_typ.h
    src/wolfssl/openssl/ripemd.h
    src/wolfssl/openssl/pem.h
    src/wolfssl/openssl/rsa.h
    src/wolfssl/openssl/ssl.h
    src/wolfssl/openssl/sha.h
    src/wolfssl/openssl/opensslconf.h
    src/wolfssl/openssl/rand.h
    src/wolfssl/openssl/stack.h
    src/wolfssl/openssl/ui.h
    src/wolfssl/openssl/x509.h
    src/wolfssl/openssl/ssl23.h
    src/wolfssl/openssl/x509v3.h
    src/wolfssl/wolfcrypt/aes.h
    src/wolfssl/wolfcrypt/arc4.h
    src/wolfssl/wolfcrypt/asn.h
    src/wolfssl/wolfcrypt/asn_public.h
    src/wolfssl/wolfcrypt/blake2-impl.h
    src/wolfssl/wolfcrypt/blake2-int.h
    src/wolfssl/wolfcrypt/async.h
    src/wolfssl/wolfcrypt/blake2.h
    src/wolfssl/wolfcrypt/camellia.h
    src/wolfssl/wolfcrypt/chacha.h
    src/wolfssl/wolfcrypt/chacha20_poly1305.h
    src/wolfssl/wolfcrypt/cmac.h
    src/wolfssl/wolfcrypt/compress.h
    src/wolfssl/wolfcrypt/curve25519.h
    src/wolfssl/wolfcrypt/coding.h
    src/wolfssl/wolfcrypt/dh.h
    src/wolfssl/wolfcrypt/dsa.h
    src/wolfssl/wolfcrypt/ecc.h
    src/wolfssl/wolfcrypt/des3.h
    src/wolfssl/wolfcrypt/ed25519.h
    src/wolfssl/wolfcrypt/error-crypt.h
    src/wolfssl/wolfcrypt/fe_operations.h
    src/wolfssl/wolfcrypt/fips_test.h
    src/wolfssl/wolfcrypt/ge_operations.h
    src/wolfssl/wolfcrypt/hash.h
    src/wolfssl/wolfcrypt/hc128.h
    src/wolfssl/wolfcrypt/hmac.h
    src/wolfssl/wolfcrypt/idea.h
    src/wolfssl/wolfcrypt/include.am
    src/wolfssl/wolfcrypt/integer.h
    src/wolfssl/wolfcrypt/md4.h
    src/wolfssl/wolfcrypt/md5.h
    src/wolfssl/wolfcrypt/md2.h
    src/wolfssl/wolfcrypt/logging.h
    src/wolfssl/wolfcrypt/mem_track.h
    src/wolfssl/wolfcrypt/misc.h
    src/wolfssl/wolfcrypt/mpi_class.h
    src/wolfssl/wolfcrypt/memory.h
    src/wolfssl/wolfcrypt/mpi_superclass.h
    src/wolfssl/wolfcrypt/pkcs7.h
    src/wolfssl/wolfcrypt/poly1305.h
    src/wolfssl/wolfcrypt/pkcs12.h
    src/wolfssl/wolfcrypt/random.h
    src/wolfssl/wolfcrypt/pwdbased.h
    src/wolfssl/wolfcrypt/ripemd.h
    src/wolfssl/wolfcrypt/rabbit.h
    src/wolfssl/wolfcrypt/sha.h
    src/wolfssl/wolfcrypt/rsa.h
    src/wolfssl/wolfcrypt/sha256.h
    src/wolfssl/wolfcrypt/sha512.h
    src/wolfssl/wolfcrypt/settings.h
    src/wolfssl/wolfcrypt/srp.h
    src/wolfssl/wolfcrypt/tfm.h
    src/wolfssl/wolfcrypt/signature.h
    src/wolfssl/wolfcrypt/visibility.h
    src/wolfssl/wolfcrypt/wc_port.h
    src/wolfssl/wolfcrypt/types.h
    src/wolfssl/wolfcrypt/wolfevent.h
    src/wolfssl/wolfcrypt/wc_encrypt.h
    src/wolfssl/wolfcrypt/wolfmath.h
    src/wolfssl/wolfcrypt/port/nrf51.h
    src/wolfssl/wolfcrypt/port/atmel/atmel.h
    src/wolfssl/wolfcrypt/port/intel/quickassist.h
    src/wolfssl/wolfcrypt/port/intel/quickassist_mem.h
    src/wolfssl/wolfcrypt/port/cavium/cavium_nitrox.h
    src/wolfssl/wolfcrypt/port/nxp/ksdk_port.h
    src/wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h
    src/wolfssl/wolfcrypt/port/ti/ti-ccm.h
    src/wolfssl/wolfcrypt/port/ti/ti-hash.h
attempting to compile firmware 
downloading binary from: /v1/binaries/596fee8ca3c4e51405d98936
saving to: photon_firmware_1500507769795.bin
Memory use: 
   text	   data	    bss	    dec	    hex	filename
  97772	    124	   2116	 100012	  186ac	/workspace/target/workspace.elf

Compile succeeded.
Saved firmware to: /Users/cermak/Software/particle/libraries/wolfssl/photon_firmware_1500507769795.bin

This works connecting to a basic https site.

The next step is to get the certificates installed so you can connect to the API and you should be off to the races.

Thanks @cermak -

I’ll give that a try on my Windoze10 machine and see what I can see. I’ll also be watching for any additional updates you’ll make as well.

I concur with your memory overhead concerns, and with your notion of a more direct means than the webhook() pub/sub operations. My application doesn’t require a whole lotta code space, but I’ve yet to see what this SSL lib overhead requires.

@jimini - ok, I quickly cobbled together a local toolchain version that can ping the AWS IoT API. It just needs the certificates added to the SSL context and appropriate arguments sent with the https request.

Github branch mqtt: https://github.com/jr3cermak/particle/tree/mqtt/localtoolchain/wolfiot
EDIT: now on master

Drop the wolfiot directory into the path of your local toolchain and compile:
make all PLATFORM=photon APPDIR=../../wolfiot

See:

RobPro:modules cermak$ particle flash --serial wolfiot/target/wolfiot.bin;particle serial monitor --follow
! PROTIP: Hold the SETUP button on your device until it blinks blue!
? Press ENTER when your device is blinking BLUE 
sending file: wolfiot/target/wolfiot.bin

Flash success!
Polling for available serial device...
Opening serial monitor for com port: "/dev/cu.usbmodem1421"
Serial monitor opened successfully:
Restarting system to apply firmware update...
Serial connection closed.  Attempting to reconnect...
Serial monitor opened successfully:
Connected to data.iot.us-west-2.amazonaws.com
SSL version is TLSv1.2
SSL cipher suite is TLS_DHE_RSA_WITH_AES_256_CBC_SHA
client.available():128
Server response: HTTP/1.1 403 Forbidden
content-type: application/json
content-length: 91
date: Thu, 20 Jul 2017 04:19:18 GMT
x-amzn-RequestId: 09e08dc9-d932-d372-d859-90b2f4aa8027
x-amzn-ErrorType: ForbiddenException:

{"message":"Missing Authentication Token","traceId":"09e08dc9-d932-d372-d859-90b2f4aa8027"}
Connection complete.

There is nothing special in the Private.h file but eventual settings I never want to publish to github. That file should go into inc.

Private.h

/* Configuration */
#define DEFAULT_MQTT_HOST       "data.iot.us-west-2.amazonaws.com" /* broker.hivemq.com */
#define DEFAULT_CMD_TIMEOUT_MS  30000
#define DEFAULT_CON_TIMEOUT_MS  5000
#define DEFAULT_MQTT_QOS        MQTT_QOS_1
#define DEFAULT_KEEP_ALIVE_SEC  60
#define DEFAULT_CLIENT_ID       "WolfMQTTClient"
#define WOLFMQTT_TOPIC_NAME     "wolfMQTT/example/"
#define DEFAULT_TOPIC_NAME      WOLFMQTT_TOPIC_NAME"testTopic"

#define MAX_BUFFER_SIZE         1024
#define TEST_MESSAGE            "42"
#define TEST_TOPIC_COUNT        1

/* Certificates */

const unsigned char CAcert[] = "\
-----BEGIN CERTIFICATE-----\
....
-----END CERTIFICATE-----";

const unsigned char CLcert[] = "\
-----BEGIN CERTIFICATE-----\
....
-----END CERTIFICATE-----";

const unsigned char PRcert[] = "\
-----BEGIN RSA PRIVATE KEY-----\
....
-----END RSA PRIVATE KEY-----";

Add your certs and I believe the SSL context can be populated with the above certificates using Section 7.5 of the wolfssl manual. The NO_FILESYSTEM option.

My next block of time is to test this, hopefully. I believe the three routines needed to seed the CTX are:

// Load CA / Root CA certificate
int wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX*, const unsigned
                                   char*, long, int)
// Load cert.pem
int wolfSSL_CTX_use_certificate_buffer(WOLFSSL_CTX*, const unsigned 
                                      char*, long, int)
// Load privkey.pem
int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX*, const unsigned 
                                     char*, long, int)

Arguments:

  • SSL CTX (context)
  • certificate string
  • string size
  • type: SSL_FILETYPE_PEM

Fantastic @cermak, thanks for your efforts here.
I will give this a whirl once I complete some hardware integration/fabrication so I can install a Photon on premise.

Getting closer. I am unable to load the IoT CA cert as I get a return error of -150.

Synced with time server.
Return code: -150
Failed to load CAcert.
Not connecting as certificate load failed.

I know the Photon is correctly synced with time and the other 2 certificates are loading fine since I do not see output. This means I am doing something bad with pulling the correct time into the library.

wolfssl/wolfcrypt/error-crypt.h: ASN_BEFORE_DATE_E = -150, /* ASN date error, current date before */

The certs in the Private.h need line feeds to be parsed correctly.

const unsigned char CAcert[] = "\
-----BEGIN CERTIFICATE-----\n\
MIIE0zCCA7....\n\
....
-----END CERTIFICATE-----\n";

Hopefully, one last battle with time.