ESP8266 RTOS 下 wolfSSL 内存开销分析和测试方法

1. 摘要

本文主要列举实际测试的 wolfSSL 在各种配置参数下,SSL 握手的内存开销和相应的测试方法。

2. 测试版本和方法

ESP8266 SDK 版本:ESP8266_RTOS_SDK - c7b64043

git clone https://github.com/espressif/ESP8266_RTOS_SDK.git

git checkout c7b64043

wolfSSL 版本: https://github.com/wolfSSL/wolfssl/releases/tag/v3.12.2-stable

下载完毕后请参照ESP8266 wolfSSL 入门指南搭建工程。

测试思路是在每次内存分配就记录剩余的内存,并在最终打印握手过程中的最小剩余内存以及最终剩余内存。代码修改方法如下:

  1. 找到 malloc 的具体实现函数pvPortMalloc,位于 ESP8266_RTOS_SDK/third_party/freertos/heap_4.c,在里面添加全局统计变量:

    size_t s_mem_mark;
    
  2. 添加复位 API 和 获取 API:

    size_t get_mem_mark(void)
    {
        return s_mem_mark;
    }
    
    void reset_mem_mark(void)
    {
        s_mem_mark = (size_t)-1;
    }
    
  3. 添加统计功能,在 pvPortMalloc 函数的返回结果(return pvReturn)之前添加如下代码:

    if (pvReturn) {
        extern size_t system_get_free_heap_size(void);
    
        size_t mem_size = system_get_free_heap_size();
        if (mem_size < s_mem_mark)
            s_mem_mark = mem_size;
    }
    
  4. 直接运行位于 ESP8266_RTOS_SDK/third_party 下的脚本 make_lib.sh 生成新的 libfreertos.a,命令如下:

    ./make_lib.sh freertos
    

测试代码代码修改如下:

  1. 找到 esp8266-wolfssl/blob/master/user/wolfssl_client/wolfssl_client.c,添加全局API 声明:

    extern size_t get_mem_mark(void);
    extern void reset_mem_mark(void);
    extern size_t system_get_free_heap_size(void);
    
  2. ret = wolfSSL_Init(); 之前添加:

    reset_mem_mark();
    printf("start heap %d\n", system_get_free_heap_size());
    
  3. 在以下代码

    ret = wolfSSL_connect(ssl);
    if (!ret) {
        goto failed4;
    }
    

    下方添加:

    printf("min heap %d\n", get_mem_mark());
    printf("end heap %d\n", system_get_free_heap_size());
    

    SSL server 代码部分也做类似的修改。

通过以上的修改,可以统计出 SSL 握手之前的内存,握手中系统剩余的最小内存和握手结束以后的内存。为了测试方便可以用2个 ESP8266 模组进行测试,1个做 server,1个做 client,通过 user_config.h 配置 WIFI 和连接参数进行测试。

3. 测试数据

本章主要列举各种配置参数和具体测试数据,由于 wolfSSL 宏观上不需要用户自己配置 fragment,所以也就不做相关的测试了,而且默认支持最大 RSA4096 计算,所以也就不做秘钥大于4096的测试。

3.1 client 模式

本节具体列举了 client 模式下非认证,本地认证,双向认证模式下,配置各种大小证书所消耗的内存。

3.1.1 非认证证书测试

测试非认证模式下各证书加秘钥总大小和内存开销的关系。

3.1.1.1.数据

server 使用 RSA2048 — RSA8192 的秘钥和生成的证书。

证书和秘钥/B开始最小最大最大消耗/B最后消耗/B
2936351521958431736155683416
4065351521694431736182083416
5195351521429631736208563416

3.1.2 单向认证证书测试

测试单向认证模式下各证书加秘钥总大小和内存开销的关系。

3.1.2.1 数据

server 使用 RSA2048 - RSA8192 的秘钥和生成的证书。

证书和秘钥/B开始最小最大最大消耗/B最后消耗/B
4197358321912032008167123824
5679354801648031528190003952
7155351281351231040216164088

3.1.3 双向认证证书测试

测试双向认证模式下各证书加秘钥大小和内存开销的关系。

3.1.3.1 数据

server 使用 RSA2048 — RSA8192 的秘钥和生成的证书,以下表格首项为 client 和 server 端认证证书,证书和秘钥的总和。

证书和秘钥/B开始最小最大最大消耗/B最后消耗/B
8394353201019228544251286776
1135833680299225800306887880

3.2 server 模式

本节具体列举了 server 模式下非认证模式,双向认证模式和配置各种大小的证书所消耗的内存。

3.2.1 非认证证书测试

测试非认证模式下各证书加秘钥大小和内存开销的关系。

3.2.1.1 数据

server 使用 RSA2048 — RSA8192 的秘钥和生成的证书,以下首项为 server 端证书和秘钥的总和。

证书和秘钥/B开始最小最大最大消耗/B最后消耗/B
29653663213368261842326410448
4097355927352238962824011696

3.2.2 双向认证证书测试

测试双向认证模式下各证书加秘钥大小和内存开销的关系。

3.2.2.1 数据

server 使用 RSA2048 — RSA8192 的秘钥和生成的证书,以下首项为 server 端证书和秘钥的总和。

证书和秘钥/B开始最小最大最大消耗/B最后消耗/B
42263533611688244882364810848
5729338485192217282865612120

4. 帮助

  • cert.sh 用于生成测试使用的证书,openssl.cnf 为生成证书的配置文件,可以通过修改 cert.sh 中的全局变量 KEY_BITS 来起到修改证书的大小的作用,直接修改其他参数也能实现,但是感觉意义不大

  • 如果手头只有1个 ESP8266 模组,可以使用 openssl 命令来创建 client 和 server 进行测试,参考链接如下:

    client: http://blog.csdn.net/as3luyuan123/article/details/16812071

    server: http://blog.csdn.net/as3luyuan123/article/details/16850727

5. 附件

cert.sh

#!/bin/bash

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")

ROOT_SUBJECT="/C=C1/ST=JS1/L=WX1/O=ESP1/OU=ESP1/CN=Server1 CA/emailAddress=ESP1"
LEVEL2_SUBJECT="/C=C2/ST=JS22/L=WX22/O=ESP22/OU=ESP22/CN=Server22 CA/emailAddress=ESP22"
LEVEL3_SUBJECT="/C=C3/ST=JS333/L=WX333/O=ESP333/OU=ESP333/CN=Server333 CA/emailAddress=ESP333"

SERVER_CERT_NAME="RootCA.crt"
SERVER_KEY_NAME="root-key.key"

CLIENT_CERT_NAME="RootCA.crt"
CLIENT_KEY_NAME="root-key.key"

KEY_BITS="4096"

echo "create root CA key"
openssl genrsa -out root-key.key $KEY_BITS
echo ----------------------
echo "create root cert request"
openssl req -new -key root-key.key -out root-req.csr -text -subj $ROOT_SUBJECT
echo ----------------------
echo "create root self sign cert"
openssl x509 -req -in root-req.csr -out RootCA.crt -sha1 -signkey root-key.key -days 3650 -text -extfile openssl.cnf -extensions v3_ca

echo "create 2 level cert key"
openssl genrsa -out root-mid.key $KEY_BITS
echo ----------------------
echo "create 2 level cert csr"
openssl req -new -key root-mid.key -out root-mid.csr -text -subj $LEVEL2_SUBJECT
echo ----------------------
echo "sign with root-crt"
openssl x509 -req -in root-mid.csr -CA RootCA.crt -CAkey root-key.key -CAcreateserial -days 3650 -out RootMid.crt -text -extfile openssl.cnf -extensions v3_ca

echo "create 3 level cert key"
openssl genrsa -out server.key $KEY_BITS
echo "create 3 level cert csr"
openssl req -new -key server.key -out server.csr -text -subj $LEVEL3_SUBJECT
echo "sign with level2 cert-crt"
openssl x509 -req -in server.csr -CA RootMid.crt -CAkey root-mid.key -CAcreateserial -days 3560 -out Server.crt -text -extfile openssl.cnf -extensions v3_ca

echo ""
echo ----------------------
echo "server uses certification " $SERVER_CERT_NAME " and key " $SERVER_KEY_NAME
echo "client uses certification " $CLIENT_CERT_NAME " and key " $CLIENT_KEY_NAME

rm *.csr *.srl

IFS=$SAVEIFS

openssl.cnf

################################################################ 
# openssl example configuration file. 
# This is mostly used for generation of certificate requests. 
################################################################# 
[ ca ] 
default_ca= CA_default          # The default ca section 
################################################################# 

[ CA_default ] 

dir=~/tmp/cert                   # Where everything is kept 
certs=$dir                       # Where the issued certs are kept 
crl_dir= $dir/crl                # Where the issued crl are kept 
database= $dir/index.txt         # database index file 
new_certs_dir= $dir/new_certs    # default place for new certs 
certificate=$dir/CA/OrbixCA      # The CA certificate 
serial= $dir/serial              # The current serial number 
crl= $dir/crl.pem                # The current CRL 
private_key= $dir/CA/OrbixCA.pk  # The private key 
RANDFILE= $dir/.rand             # private random number file 
default_days= 365                # how long to certify for 
default_crl_days= 30             # how long before next CRL 
default_md= md5                  # which message digest to use 
preserve= no                     # keep passed DN ordering 

# A few different ways of specifying how closely the request should 
# conform to the details of the CA 

policy= policy_match            # For the CA policy 

[ policy_match ]  
countryName= match 
stateOrProvinceName= match 
organizationName= match 
organizationalUnitName= optional 
commonName= supplied 
emailAddress= optional 

# For the `anything' policy 
# At this point in time, you must list all acceptable `object' 
# types 

[ policy_anything ] 
countryName = optional 
stateOrProvinceName= optional 
localityName= optional 
organizationName = optional 
organizationalUnitName = optional 
commonName= supplied 
emailAddress= optional 

[ req ] 
default_bits = 1024 
default_keyfile= privkey.pem 
distinguished_name = req_distinguished_name 
attributes = req_attributes 
x509_extensions = v3_ca

[ req_distinguished_name ] 
countryName= Country Name (2 letter code) 
countryName_min= 2 
countryName_max = 2 
stateOrProvinceName= State or Province Name (full name) 
localityName = Locality Name (eg, city) 
organizationName = Organization Name (eg, company) 
organizationalUnitName  = Organizational Unit Name (eg, section) 
commonName = Common Name (eg. YOUR name) 
commonName_max = 64 
emailAddress = Email Address 
emailAddress_max = 40 

[ req_attributes ] 
challengePassword = A challenge password 
challengePassword_min = 4 
challengePassword_max = 20 
unstructuredName= An optional company name

[ v3_ca ]
basicConstraints = CA:true
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值