# \[RT-117x]Signing image with the HSM (SignServer)

在本文档中介绍如何使用sign server来对X-NAV的image进行签名。

## 1. PKI 体系 <a href="#id-1.pki-ti-xi" id="id-1.pki-ti-xi"></a>

根据NXP-RT1176的secure boot的文档，<https://app.gitbook.com/o/eTBeA3vhkOtihTJASkhd/s/tqiX1ZbXhRorHX3bwk1r/~/changes/13/rt1170_documents/rt-117x-i.mx-rt1170s-secure-boot>

<figure><img src="https://1204947731-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FtqiX1ZbXhRorHX3bwk1r%2Fuploads%2FBrYse6qvrY74NSAWCT8x%2Fimage.png?alt=media&#x26;token=35fc44cb-f8ca-44c2-aabf-81d589319224" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1204947731-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FtqiX1ZbXhRorHX3bwk1r%2Fuploads%2FdywJqG37EWqofQTAmzwD%2Fimage.png?alt=media&#x26;token=f1b49fb0-8fcf-49f3-9047-f718e7bab146" alt=""><figcaption></figcaption></figure>

需要**角色**为：

* root CA （用于公钥的认证） 对应PKI体系图中的CA
* Level 1：Sign Server （在NXP中叫做SRK， super root key，二级证书）对应SRK1
* Level 2: CSF signer（用于对CSF header签名）
* Level2: IMAGE signer（用于对IMAGE签名）

**需要给到车端的证书：**

* ca.crt文件 （1个）
* srk.crt文件 （4个）
* csf.crt文件（4个）
* img.crt文件（4个）

其中4个srk.crt文件要组成列表计算hash放入eFUSE中，其中csf.crt和img.crt文件需要放入boot image的header中，其中ca.crt和srk.crt需要组成证书链用于image和csf的验签过程。

关于Key和Cert的生成要求，参见：<https://github.com/carloscn/rt117x-bsp/blob/master/tools/flashprog/gen_ca_cert.sh>

## 2. 签名要求 <a href="#id-2.-qian-ming-yao-qiu" id="id-2.-qian-ming-yao-qiu"></a>

签名使用CMS\_sign，参考：<https://www.openssl.org/docs/man3.1/man3/CMS_sign.html>

### 2.1 接口要求 <a href="#id-2.1-jie-kou-yao-qiu" id="id-2.1-jie-kou-yao-qiu"></a>

使用SHA2\_256作为digest，接口要求（抽象为下面的伪代码接口）：

***sign\_request(srk\_number, csf\_or\_img\_signer, origin\_sign\_data)：***

输入参数：

* srk\_number: srk序列号（只有4个），在PKI体系图中对应SRK1-4
* csf\_or\_img\_signer：signer选择（只有2种），CSF signer或者IMAGE signer
* original\_sign\_data：签名的二进制数据的原始数据，几个字节到几十兆不等，通常低于1MB。

输出参数：

* CMS blob格式的签名二进制文件（DER格式）参考：[8.0\_Security\_pkcs7(CMS)\_embedded](https://github.com/carloscn/blog/issues/186)

注意CMS生成的二进制flags：

`CMS_DETACHED | CMS_NOCERTS | CMS_NOSMIMECAP | CMS_BINARY;`

这里有个sign的示例可以在这个工具中：

{% @github-files/github-code-block url="<https://github.com/carloscn/rt117x-bsp/tree/master/tools/cms_sign_verify_tool>" %}

如何运行？

`make`

`make sign`

<figure><img src="https://1204947731-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FtqiX1ZbXhRorHX3bwk1r%2Fuploads%2FNQoLPfqOtLgOhDuHGmg5%2Fimage.png?alt=media&#x26;token=5a7e655a-2634-4b81-bf03-ddd8753cab6d" alt=""><figcaption></figcaption></figure>

这里面分别有sign之前的数据和sign之后的数据。

### 2.2 签名验证 <a href="#id-2.2-qian-ming-yan-zheng" id="id-2.2-qian-ming-yan-zheng"></a>

提供签名的验证工具，可以帮助你初步的快速的验证签名的数据。

`make verify`

<figure><img src="https://1204947731-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FtqiX1ZbXhRorHX3bwk1r%2Fuploads%2FXJAsjJhi3tqdx0j9CRu5%2Fimage.png?alt=media&#x26;token=221cb17f-deb3-4773-8113-29fbaa889dea" alt=""><figcaption></figcaption></figure>

## 3. NXP签名格式测试用例 <a href="#id-3.nxp-qian-ming-ge-shi-ce-shi-yong-li" id="id-3.nxp-qian-ming-ge-shi-ce-shi-yong-li"></a>

{% embed url="<https://www.openssl.org/docs/manmaster/man1/openssl-cms.html>" %}

以下为使用openssl命令行模拟NXP签名格式的测试用例（**请注意参数**）：

```bash
# !/bin/bash

rm -rf signed_imgsig.bin.cmdline

echo "[INFO] sign imgsig.bin.dup file."
openssl cms -sign -signer keys/IMG1_1_sha256_2048_65537_v3_usr_crt.pem \
            -CAfile keys/ca_cert_chains.crt \
            -inform der \
            -inkey keys/IMG1_1_sha256_2048_65537_v3_usr_key.pem \
            -md sha256 \
            -outform DER \
            -in imgsig.bin.dup \
            -out signed_imgsig.bin.cmdline \
            -passin pass:test \
            -binary \
            -nocerts \
            -nosmimecap
if [ $? -ge 1 ]; then
    echo "[ERR] sign failed!"
    exit 2
fi

echo "[INFO] verify signed_imgsig.bin.cmdline file."
openssl cms -verify -certfile keys/IMG1_1_sha256_2048_65537_v3_usr_crt.pem \
            -inform der \
            -CAfile keys/ca_cert_chains.crt \
            -in signed_imgsig.bin.cmdline \
            -content imgsig.bin.dup \
            -binary \
            -nocerts \
            -nosmimecap \
            -nodetach > /dev/null
if [ $? -ge 1 ]; then
    echo "[ERR] verify failed!"
    exit 2
fi
echo "[INFO] done!"

```

{% file src="<https://1204947731-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FtqiX1ZbXhRorHX3bwk1r%2Fuploads%2Fb68q2BoWf2I9lv1lg1uZ%2Fsign_verify_example.zip?alt=media&token=f9057ebf-0d26-4604-bd7d-eb49c82a9030>" %}
