ESP8266 基础篇:mbedTLS 内存开销分析

1. 摘要

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

2. 测试方法

测试版本:ESP8266_RTOS_SDK - c7b64043

测试思路是原子级的测试内存的开销,也就是说每次只要有内存分配就统计剩余的内存。代码修改方法如下:

  1. 找到 malloc的具体实现函数pvPortMalloc,位于 ESP8266_RTOS_SDK/third_party/freertos/heap_4.c

在里面添加全局统计变量:

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

    size_t get_mem_mark(void)
    {
        return s_mem_mark;
    }
    
    void reset_mem_mark(void)
    {
        s_mem_mark = (size_t)-1;
    }
    
  2. 添加统计功能,在 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;
    }
    

测试代码代码修改如下:

  1. 找到 ESP8266_RTOS_SDK/examples/openssl_demo/programs/openssl_demo.c,添加全局API 声明:

extern size_t get_mem_mark(void);
extern void reset_mem_mark(void);
extern size_t system_get_free_heap_size(void);
```

  1. os_printf("create SSL context ......"); 之前添加:

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

     ret = SSL_connect(ssl);
     if (!ret) {
         os_printf("failed, return [-0x%x]\n", -ret);
         goto failed7;
     }
     os_printf("OK\n");
    

    下方添加:

     os_printf("min heap %d\n", get_mem_mark());
     os_printf("end heap %d\n", system_get_free_heap_size());
    
     while (1);
    

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

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

3. 测试数据

本章主要列举各种配置参数和具体测试数据。

3.1 client 模式

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

3.1.1 非认证 Fragment 测试

测试非认证模式下各 fragment大小和内存开销的关系,限定测试条件如下:

  • RSA2048 加密
  • 秘钥大小 1704 Bytes
  • 证书大小 1261 Bytes
3.1.1.1 数据
Fragment/B开始最小最大最大消耗/B最后消耗/B
20484144025496297121594411728
30724144023448276641799213776
40964144021400256162004015824
51204128819352235682193617720
61444155217304215202424820032
71684144015256194722618421968
81924128813208174162808023872

3.1.2 本地认证 Fragment 测试

测试本地认证模式下各 fragment大小和内存开销的关系,限定测试条件如下:

  • RSA2048 加密
  • 秘钥大小 1704 Bytes
  • 证书大小 1261 Bytes
  • 认证证书大小 1261 Bytes
3.1.2.1 数据
Fragment/B开始最小最大最大消耗/B最后消耗/B
20484144023666270441777414396
30724144020938250002050216440
40964144018882229442255818496
51204128816686205882460220700
61444155214910189962664222556
71684144012754168242868624616
81924128810578146163071026672

3.1.3 双向认证 Fragment 测试

测试双向认证模式下各 fragment大小和内存开销的关系,限定测试条件如下:

  • RSA2048 加密
  • 秘钥大小 1704 Bytes
  • 证书大小 1261 Bytes
  • CA证书大小 1261 Bytes
3.1.3.1 数据
Fragment/B开始最小最大最大消耗/B最后消耗/B
20484144020718234722072217968
30724144017342214242409820016
40964144014854190362658622404
51204128813086171722820224116
61444155210942153283061026224
7168414409118131923232228248
8192412886914109683437430320

3.1.4 非认证证书测试

测试非认证模式下各证书加秘钥总大小和内存开销的关系,限定测试条件如下:

  • fragment 为 5KB
3.1.4.1.数据

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

证书和秘钥/B开始最小最大最大消耗/B最后消耗/B
29364144019774238202166617620
40654144017734203692370621071
51954144015334193842610622056
63244128813342181842794623104
74494155210178174403137424112

3.1.5 单向认证证书测试

测试单向认证模式下各证书加秘钥总大小和内存开销的关系,限定测试条件如下:

  • fragment 为 5KB
3.1.5.1 数据

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

证书和秘钥/B开始最小最大最大消耗/B最后消耗/B
41974144016726211242471420316
56794144013410169402803024500
71554144010606155643083425876
8633412886990135683429827720

3.1.6 双向认证证书测试

测试双向认证模式下各证书加秘钥大小和内存开销的关系,限定测试条件如下:

  • fragment 为 5KB
3.1.6.1 数据

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

证书和秘钥/B开始最小最大最大消耗/B最后消耗/B
83944144013198172722824224168
11358414408370122403307029200
1431041440659098403485031600

3.2 server 模式

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

3.2.1 非认证 Fragment 测试

测试非认证模式下各 fragment大小和内存开销的关系,限定测试条件如下:

  • RSA2048 加密
  • 秘钥大小 1704 Bytes
  • 证书大小 1261 Bytes
3.2.1.1 数据
Fragment/B开始最小最大最大消耗/B最后消耗/B
20484144014942232882649818152
30724144012909212752853120165
40964144010877192653056322175
5120412888694171033259424185
6144415526927153573462526195

3.2.2 双向认证 Fragment 测试

测试双向认证模式下各 fragment大小和内存开销的关系,限定测试条件如下:

  • RSA2048 加密
  • 秘钥大小 1704 Bytes
  • 证书大小 1261 Bytes
3.2.2.1 数据
Fragment/B开始最小最大最大消耗/B最后消耗/B
20484144011182178683025823572
3072414408727157843271325656
4096414406275137023516527738

3.2.3 非认证证书测试

测试非认证模式下各证书加秘钥大小和内存开销的关系,限定测试条件如下:

  • fragment 为 3KB
3.2.3.1 数据

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

证书和秘钥/B开始最小最大最大消耗/B最后消耗/B
29654144012994214682844619972
4097414408607196903283321750

3.2.4 双向认证证书测试

测试双向认证模式下各证书加秘钥大小和内存开销的关系,限定测试条件如下:

  • fragment 为 3KB
3.2.4.1 数据

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

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

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值