# CRYPTO Devices

Encryption/Decryption is a file and message encryption and decryption technology. With the rapid development of the Internet of Things, users have a strong demand for data encryption and decryption in their normal work.

To ensure the information security of IoT devices, the TLS secure transport layer protocol was introduced at the software level. At the same time, security-related encryption and decryption modules were gradually added to hardware chips, and even security chips designed specifically for security appeared. The hardware security module on the chip has a faster computing speed and smaller resource usage than the security algorithm implemented purely by software. However, most IoT devices still use pure software security algorithms. One of the most important reasons is that the hardware interfaces are different and diverse, making it difficult to connect with software.

Therefore, RT-Thread launched the hwcrypto hardware encryption and decryption driver framework and connected it to common security transmission kits. As long as the hardware supports the encryption and decryption module, the hardware-based encryption and decryption security transmission kit can be used directly, and the transmission speed can be increased several times.

### [CRYPTO Introduction](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=crypto-%e7%ae%80%e4%bb%8b) <a href="#crypto-jian-jie" id="crypto-jian-jie"></a>

#### [Framework Introduction](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e6%a1%86%e6%9e%b6%e7%ae%80%e4%bb%8b) <a href="#kuang-jia-jian-jie" id="kuang-jia-jian-jie"></a>

hwcrypto is a hardware encryption and decryption device driver framework. It is mainly composed of two parts: the hardware encryption and decryption driver abstraction layer and various encryption and decryption API interfaces. For upper-layer applications, it can be connected to a security suite or used directly, and the usage is very flexible. For the driver, there are few interfaces to be connected, the function is single, and the driver development is simple and fast. The following figure is a Crypto framework hierarchy diagram:

![Crypto](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/figures/framework.png)

The main **features** are as follows:

* **Thin and light design, efficient operation**

The most important function of the hardware encryption and decryption driver is interface conversion, which realizes interface unification and facilitates upper-layer applications to use hardware encryption and decryption. Therefore, it is designed to be very thin and light. It has extremely low resource usage, ROM < 0.8K / RAM < 0.2K.

Encryption and decryption also have very high requirements on running speed. Therefore, for frequently called code, careful consideration is given to reduce the steps of the running process to a minimum, so as to minimize the performance loss, and make it as fast as directly operating the hardware registers.

* **Thoughtful and easy to use**

In API design, we start from two dimensions: simplicity and ease of use, and full functionality. First, users directly use the hardware encryption and decryption API, which requires easy to use. For this reason, we evaluated many software interfaces in the early stage. After personal use and testing, we finally defined a set of APIs with full functionality and simple interfaces.

While meeting the needs of users, we also made a lot of considerations in the connection with the secure transmission suite. We added an API specifically for the secure transmission suite. In the end, this set of API users can use or connect to the secure transmission suite with ease.

* **Fully compatible and versatile**

The interface design of the driver docking is also carefully designed. In the early stage, the encryption and decryption peripherals of many hardware manufacturers were classified according to their functions, analyzed and sorted, and a set of driver interfaces with single functions and comprehensive parameters were extracted. This driver interface can fully adapt to conventional MCU encryption and decryption peripherals. It has been verified on multiple platforms, such as Lianshengde W60X series, STM32 series, etc.

#### [Function Introduction](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e5%8a%9f%e8%83%bd%e7%ae%80%e4%bb%8b) <a href="#gong-neng-jian-jie" id="gong-neng-jian-jie"></a>

The hardware encryption and decryption framework currently supports encryption and decryption related interfaces such as AES/DES/3DES/RC4/SHA1/SHA2/MD5/CRC/RNG/BIGNUM.

The above encryption and decryption algorithms are divided into the following categories according to different types. Each category has rich APIs available for use. The currently supported types are as follows:

* hash: hash algorithm
* symmetric: symmetric encryption and decryption algorithm
* gcm: GMAC message authentication code
* crc: CRC redundancy check
* rng: random number generator
* bignum: large number operations

### [Hash Algorithm](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=hash-%e7%ae%97%e6%b3%95) <a href="#hash-suan-fa" id="hash-suan-fa"></a>

A hash algorithm transforms an input of any length into an output of a fixed length through a hash algorithm. It is a function that compresses a message of any length into a message digest of a fixed length. The space of hash values ​​is usually much smaller than the space of inputs. Different inputs may hash to the same output, so it is impossible to determine the unique input value from the hash value.

#### [Access hash algorithm device](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%bf%e9%97%ae-hash-%e7%ae%97%e6%b3%95%e8%ae%be%e5%a4%87) <a href="#fang-wen-hash-suan-fa-she-bei" id="fang-wen-hash-suan-fa-she-bei"></a>

The application accesses the hash algorithm device hardware through the hash algorithm device management interface provided by RT-Thread. The relevant interface is as follows:

| function                        | describe                       |
| ------------------------------- | ------------------------------ |
| rt\_hwcrypto\_hash\_create()    | Creating a hash context        |
| rt\_hwcrypto\_hash\_destroy()   | Release context                |
| rt\_hwcrypto\_hash\_finish()    | Calculate the final hash value |
| rt\_hwcrypto\_hash\_update()    | Process a packet of data       |
| rt\_hwcrypto\_hash\_cpy()       | Copy context                   |
| rt\_hwcrypto\_hash\_reset()     | Reset Context                  |
| rt\_hwcrypto\_hash\_set\_type() | Set the hash algorithm type    |

#### [Creating a hash context](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e5%88%9b%e5%bb%ba-hash-%e4%b8%8a%e4%b8%8b%e6%96%87) <a href="#chuang-jian-hash-shang-xia-wen" id="chuang-jian-hash-shang-xia-wen"></a>

The application creates a hash context based on the handle of the hash device as follows:

```c
struct rt_hwcrypto_ctx *rt_hwcrypto_hash_create(struct rt_hwcrypto_device *device,
                                                hwcrypto_type type);copymistakeCopy Success
```

| **parameter** | **describe**                            |
| ------------- | --------------------------------------- |
| device        | Encryption and decryption device handle |
| type          | Hash algorithm type                     |
| **return**    | ——                                      |
| NULL          | fail                                    |
| other         | Device Object                           |

Common types and subtypes of hash algorithms are as follows

```c
    /* HASH Type */
    HWCRYPTO_TYPE_MD5     = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< MD5 */
    HWCRYPTO_TYPE_SHA1    = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< SHA1 */
    HWCRYPTO_TYPE_SHA2    = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< SHA2 */

    /* SHA2 Subtype */
    HWCRYPTO_TYPE_SHA224 = HWCRYPTO_TYPE_SHA2 | (0x01 << 8),
    HWCRYPTO_TYPE_SHA256 = HWCRYPTO_TYPE_SHA2 | (0x02 << 8),
    HWCRYPTO_TYPE_SHA384 = HWCRYPTO_TYPE_SHA2 | (0x03 << 8),
    HWCRYPTO_TYPE_SHA512 = HWCRYPTO_TYPE_SHA2 | (0x04 << 8),
copymistakeCopy Success
```

If you create a hash algorithm of the MD5 type, the usage example is as follows

```c
    struct rt_hwcrypto_ctx *ctx;

    ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_MD5);copymistakeCopy Success
```

* The prototype of the rt\_hwcrypto\_dev\_default() function is `struct rt_hwcrypto_device *rt_hwcrypto_dev_default(void)`to return the default hardware encryption and decryption device handle.

#### [Release context](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e9%87%8a%e6%94%be%e4%b8%8a%e4%b8%8b%e6%96%87) <a href="#shi-fang-shang-xia-wen" id="shi-fang-shang-xia-wen"></a>

The application deletes the context based on the hash context and releases the resources as follows:

```c
void rt_hwcrypto_hash_destroy(struct rt_hwcrypto_ctx *ctx);copymistakeCopy Success
```

| **parameter** | **describe** |
| ------------- | ------------ |
| ctx           | Context      |
| **return**    | ——           |

#### [Calculate the final hash value](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%a1%e7%ae%97%e6%9c%80%e7%bb%88-hash-%e5%80%bc) <a href="#ji-suan-zui-zhong-hash-zhi" id="ji-suan-zui-zhong-hash-zhi"></a>

Based on the hash context, the application can output the final hash value as follows:

```c
rt_err_t rt_hwcrypto_hash_finish(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *output, rt_size_t length);copymistakeCopy Success
```

| **parameter** | **describe**        |
| ------------- | ------------------- |
| ctx           | Context             |
| output        | Output Data         |
| length        | Data length         |
| **return**    | ——                  |
| RT\_EOK       | Calculation success |
| other         | fail                |

#### [Calculate a packet of data](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%a1%e7%ae%97%e4%b8%80%e5%8c%85%e6%95%b0%e6%8d%ae) <a href="#ji-suan-yi-bao-shu-ju" id="ji-suan-yi-bao-shu-ju"></a>

The application inputs a packet of data and calculates the hash value according to the hash context, as shown below:

```c
rt_err_t rt_hwcrypto_hash_update(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *input, rt_size_t length);copymistakeCopy Success
```

| **parameter** | **describe**        |
| ------------- | ------------------- |
| ctx           | Context             |
| input         | Input Data          |
| length        | Input data length   |
| **return**    | ——                  |
| RT\_EOK       | Calculation success |
| other         | fail                |

The usage examples are as follows:

```c
int main(void)
{
    rt_uint8_t buf_in[32];
    int i;
    struct rt_hwcrypto_ctx *ctx;

    /* 填充测试数据 */
    for (i = 0; i < sizeof(buf_in); i++)
    {
        buf_in[i] = (rt_uint8_t)i;
    }
    /* 创建一个 SHA1/MD5 类型的上下文 */
    ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), type);

    /* 将输入数据进行 hash 运算 */
    rt_hwcrypto_hash_update(ctx, in, 32);
    /* 获得运算结果 */
    rt_hwcrypto_hash_finish(ctx, out, 32);
    /* 删除上下文，释放资源 */
    rt_hwcrypto_hash_destroy(ctx);
}copymistakeCopy Success
```

#### [Copy context](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e5%a4%8d%e5%88%b6%e4%b8%8a%e4%b8%8b%e6%96%87) <a href="#fu-zhi-shang-xia-wen" id="fu-zhi-shang-xia-wen"></a>

The application copies the context of the source hash to the context of the target hash as follows:

```c
rt_err_t rt_hwcrypto_hash_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src);copymistakeCopy Success
```

| **parameter** | **describe**        |
| ------------- | ------------------- |
| of the        | Target context      |
| src           | Source context      |
| **return**    | ——                  |
| RT\_EOK       | Calculation success |
| other         | fail                |

#### [Reset Context](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e9%87%8d%e7%bd%ae%e4%b8%8a%e4%b8%8b%e6%96%87) <a href="#zhong-zhi-shang-xia-wen" id="zhong-zhi-shang-xia-wen"></a>

The application resets the hash context text according to the hash context, as follows:

```c
void rt_hwcrypto_hash_reset(struct rt_hwcrypto_ctx *ctx);copymistakeCopy Success
```

| **parameter** | **describe** |
| ------------- | ------------ |
| ctx           | Context      |
| **return**    | ——           |

* Before releasing the context, the next packet of data can be calculated only after it is reset.

#### [Set the hash algorithm type](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%be%e7%bd%ae-hash-%e7%ae%97%e6%b3%95%e7%b1%bb%e5%9e%8b) <a href="#she-zhi-hash-suan-fa-lei-xing" id="she-zhi-hash-suan-fa-lei-xing"></a>

The application sets the hash algorithm type according to the hash context, as follows:

```c
rt_err_t rt_hwcrypto_hash_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type);copymistakeCopy Success
```

| **parameter** | **describe**        |
| ------------- | ------------------- |
| ctx           | Context             |
| type          | Hash algorithm type |
| **return**    | ——                  |
| RT\_EOK       | Calculation success |
| other         | fail                |

* Common hash algorithm types, refer to the type introduction in the creation of hash context
* Setting the type is only valid before data operation. Changing the type during operation will result in incorrect operation results.

### [Symmetric encryption and decryption algorithm](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e5%af%b9%e7%a7%b0%e5%8a%a0%e8%a7%a3%e5%af%86%e7%ae%97%e6%b3%95) <a href="#dui-chen-jia-jie-mi-suan-fa" id="dui-chen-jia-jie-mi-suan-fa"></a>

Symmetric encryption and decryption refers to an encryption algorithm that uses the same key for encryption and decryption, so this encryption algorithm is also called a secret key algorithm or a single key algorithm. The security of a symmetric algorithm depends on the key. Leaking the key means that anyone can decrypt the messages they send or receive, so the confidentiality of the key is crucial to the security of communication.

#### [Access to symmetric encryption and decryption devices](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%bf%e9%97%ae%e5%af%b9%e7%a7%b0%e5%8a%a0%e8%a7%a3%e5%af%86%e8%ae%be%e5%a4%87) <a href="#fang-wen-dui-chen-jia-jie-mi-she-bei" id="fang-wen-dui-chen-jia-jie-mi-she-bei"></a>

The application accesses the symmetric algorithm device hardware through the symmetric device management interface provided by RT-Thread. The relevant interface is as follows:

| function                              | describe                                                                       |
| ------------------------------------- | ------------------------------------------------------------------------------ |
| rt\_hwcrypto\_symmetric\_create()     | Create a symmetric encryption and decryption context                           |
| rt\_hwcrypto\_symmetric\_destroy()    | Release context                                                                |
| rt\_hwcrypto\_symmetric\_crypt()      | Encryption and decryption operations                                           |
| rt\_hwcrypto\_symmetric\_setkey()     | Set encryption and decryption keys                                             |
| rt\_hwcrypto\_symmetric\_getkey()     | Get encryption and decryption keys                                             |
| rt\_hwcrypto\_symmetric\_setiv()      | Set the symmetric encryption and decryption initialization vector              |
| rt\_hwcrypto\_symmetric\_getiv()      | Get the symmetric encryption and decryption initialization vector              |
| rt\_hwcrypto\_symmetric\_set\_ivoff() | Set the symmetric encryption and decryption initialization vector offset value |
| rt\_hwcrypto\_symmetric\_get\_ivoff() | Get the symmetric encryption and decryption initialization vector offset value |
| rt\_hwcrypto\_symmetric\_cpy()        | Copy context                                                                   |
| rt\_hwcrypto\_symmetric\_reset()      | Reset Context                                                                  |
| rt\_hwcrypto\_symmetric\_set\_type()  | Set the encryption and decryption type                                         |

#### [Create a symmetric encryption and decryption context](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e5%88%9b%e5%bb%ba%e5%af%b9%e7%a7%b0%e5%8a%a0%e8%a7%a3%e5%af%86%e4%b8%8a%e4%b8%8b%e6%96%87) <a href="#chuang-jian-dui-chen-jia-jie-mi-shang-xia-wen" id="chuang-jian-dui-chen-jia-jie-mi-shang-xia-wen"></a>

The application creates a symmetric encryption and decryption context based on the handle of the symmetric encryption and decryption device, as shown below:

```c
struct rt_hwcrypto_ctx *rt_hwcrypto_symmetric_create(struct rt_hwcrypto_device *device, hwcrypto_type type);copymistakeCopy Success
```

| **parameter** | **describe**                                       |
| ------------- | -------------------------------------------------- |
| device        | Encryption and decryption device handle            |
| type          | Symmetric encryption and decryption algorithm type |
| **return**    | ——                                                 |
| NULL          | fail                                               |
| other         | Device Object                                      |

Common types and subtypes of symmetric encryption and decryption algorithms are as follows

```c
    /* symmetric Type */
    HWCRYPTO_TYPE_AES     = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< AES */
    HWCRYPTO_TYPE_DES     = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< DES */
    HWCRYPTO_TYPE_3DES    = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< 3DES */
    HWCRYPTO_TYPE_RC4     = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< RC4 */
    HWCRYPTO_TYPE_GCM     = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< GCM */

    /* AES Subtype */
    HWCRYPTO_TYPE_AES_ECB = HWCRYPTO_TYPE_AES | (0x01 << 8),
    HWCRYPTO_TYPE_AES_CBC = HWCRYPTO_TYPE_AES | (0x02 << 8),
    HWCRYPTO_TYPE_AES_CFB = HWCRYPTO_TYPE_AES | (0x03 << 8),
    HWCRYPTO_TYPE_AES_CTR = HWCRYPTO_TYPE_AES | (0x04 << 8),
    HWCRYPTO_TYPE_AES_OFB = HWCRYPTO_TYPE_AES | (0x05 << 8),

    /* DES Subtype */
    HWCRYPTO_TYPE_DES_ECB = HWCRYPTO_TYPE_DES | (0x01 << 8),
    HWCRYPTO_TYPE_DES_CBC = HWCRYPTO_TYPE_DES | (0x02 << 8),

    /* 3DES Subtype */
    HWCRYPTO_TYPE_3DES_ECB = HWCRYPTO_TYPE_3DES | (0x01 << 8),
    HWCRYPTO_TYPE_3DES_CBC = HWCRYPTO_TYPE_3DES | (0x02 << 8),copymistakeCopy Success
```

Create an AES-CBC encryption as follows

```c
    struct rt_hwcrypto_ctx *ctx;

    ctx = rt_hwcrypto_symmetric_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_AES_CBC);copymistakeCopy Success
```

#### [Release context](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e9%87%8a%e6%94%be%e4%b8%8a%e4%b8%8b%e6%96%87-1) <a href="#shi-fang-shang-xia-wen-1" id="shi-fang-shang-xia-wen-1"></a>

The application deletes the context based on the symmetric encryption and decryption context and releases resources as shown below:

```c
void rt_hwcrypto_symmetric_destroy(struct rt_hwcrypto_ctx *ctx);copymistakeCopy Success
```

| **parameter** | **describe**   |
| ------------- | -------------- |
| ctx           | Context Handle |
| **return**    | ——             |

#### [Encrypting and decrypting data](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e5%8a%a0%e8%a7%a3%e5%af%86%e6%95%b0%e6%8d%ae) <a href="#jia-jie-mi-shu-ju" id="jia-jie-mi-shu-ju"></a>

The application can output the final calculated value based on the context of symmetric encryption and decryption, encryption and decryption mode, input data and length, as shown below:

```c
rt_err_t rt_hwcrypto_symmetric_crypt(struct rt_hwcrypto_ctx *ctx, hwcrypto_mode mode, rt_size_t length, const rt_uint8_t *in, rt_uint8_t *out);
copymistakeCopy Success
```

| **parameter** | **describe**             |
| ------------- | ------------------------ |
| ctx           | Context Handle           |
| mode          | Encryption or decryption |
| length        | Data length              |
| in            | Input Data               |
| out           | Output Data              |
| **return**    | ——                       |
| RT\_EOK       | Calculation success      |
| other         | fail                     |

The encryption or decryption modes are as follows

```c
typedef enum
{
    HWCRYPTO_MODE_ENCRYPT = 0x1,        /**< Encryption operations */
    HWCRYPTO_MODE_DECRYPT = 0x2,        /**< Decryption operations */
    HWCRYPTO_MODE_UNKNOWN = 0x7fffffff, /**< Unknown */
} hwcrypto_mode;copymistakeCopy Success
```

#### [Set encryption and decryption keys](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%be%e7%bd%ae%e5%8a%a0%e8%a7%a3%e5%af%86%e5%af%86%e9%92%a5) <a href="#she-zhi-jia-jie-mi-mi-yao" id="she-zhi-jia-jie-mi-mi-yao"></a>

The application sets the encryption and decryption keys according to the context, key and secret key, and length of symmetric encryption and decryption, as shown below:

```c
rt_err_t rt_hwcrypto_symmetric_setkey(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *key, rt_uint32_t bitlen);copymistakeCopy Success
```

| **parameter** | **describe**         |
| ------------- | -------------------- |
| ctx           | Context Handle       |
| key           | Enter the key        |
| Bitlen        | Key length           |
| **return**    | ——                   |
| RT\_EOK       | Set key successfully |
| other         | fail                 |

#### [Get the key](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%8e%b7%e5%8f%96%e5%af%86%e9%92%a5) <a href="#huo-qu-mi-yao" id="huo-qu-mi-yao"></a>

The application obtains the key length based on the context, key, and length of symmetric encryption and decryption, as shown below:

```c
int rt_hwcrypto_symmetric_getkey(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *key, rt_uint32_t bitlen);copymistakeCopy Success
```

| **parameter** | **describe**    |
| ------------- | --------------- |
| ctx           | Target context  |
| key           | Key             |
| Bitlen        | Key length      |
| **return**    | ——              |
| int           | Copy key length |
| other         | fail            |

#### [Set the symmetric encryption and decryption initialization vector](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%be%e7%bd%ae%e5%af%b9%e7%a7%b0%e5%8a%a0%e8%a7%a3%e5%af%86%e5%88%9d%e5%a7%8b%e5%8c%96%e5%90%91%e9%87%8f) <a href="#she-zhi-dui-chen-jia-jie-mi-chu-shi-hua-xiang-liang" id="she-zhi-dui-chen-jia-jie-mi-chu-shi-hua-xiang-liang"></a>

The application sets the symmetric encryption and decryption initialization vector according to the symmetric encryption and decryption context, initialization vector, and vector length, as shown below:

```c
rt_err_t rt_hwcrypto_symmetric_setiv(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *iv, rt_size_t len);copymistakeCopy Success
```

| **parameter** | **describe**                        |
| ------------- | ----------------------------------- |
| ctx           | Context                             |
| iv            | Initialization Vector               |
| only          | Length of the initialization vector |
| **return**    | ——                                  |
| RT\_EOK       | Set up for success                  |
| other         | fail                                |

#### [Get the symmetric encryption and decryption initialization vector](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%8e%b7%e5%8f%96%e5%af%b9%e7%a7%b0%e5%8a%a0%e8%a7%a3%e5%af%86%e5%88%9d%e5%a7%8b%e5%8c%96%e5%90%91%e9%87%8f) <a href="#huo-qu-dui-chen-jia-jie-mi-chu-shi-hua-xiang-liang" id="huo-qu-dui-chen-jia-jie-mi-chu-shi-hua-xiang-liang"></a>

The application obtains the symmetric encryption and decryption initialization vector according to the symmetric encryption and decryption context, as shown below:

```c
int rt_hwcrypto_symmetric_getiv(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *iv, rt_size_t len);copymistakeCopy Success
```

| **parameter** | **describe**                        |
| ------------- | ----------------------------------- |
| ctx           | Context                             |
| iv            | Will get the initialization vector  |
| only          | Length of the initialization vector |
| **return**    | ——                                  |
| int           | Get the length of success           |
| other         | fail                                |

#### [Set the initialization vector offset for symmetric encryption and decryption](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%be%e7%bd%ae%e5%af%b9%e7%a7%b0%e5%8a%a0%e8%a7%a3%e5%af%86%e5%88%9d%e5%a7%8b%e5%8c%96%e5%90%91%e9%87%8f%e5%81%8f%e7%a7%bb) <a href="#she-zhi-dui-chen-jia-jie-mi-chu-shi-hua-xiang-liang-pian-yi" id="she-zhi-dui-chen-jia-jie-mi-chu-shi-hua-xiang-liang-pian-yi"></a>

The application sets the offset value of the symmetric encryption and decryption initialization vector according to the context of symmetric encryption and decryption and the initialization vector offset value, as shown below:

```c
void rt_hwcrypto_symmetric_set_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t iv_off);copymistakeCopy Success
```

| **parameter** | **describe**                 |
| ------------- | ---------------------------- |
| ctx           | Context                      |
| iv\_off       | Initialization vector offset |
| **return**    | ——                           |

#### [Get the symmetric encryption and decryption initialization vector offset value](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%8e%b7%e5%8f%96%e5%af%b9%e7%a7%b0%e5%8a%a0%e8%a7%a3%e5%af%86%e5%88%9d%e5%a7%8b%e5%8c%96%e5%90%91%e9%87%8f%e5%81%8f%e7%a7%bb%e5%80%bc) <a href="#huo-qu-dui-chen-jia-jie-mi-chu-shi-hua-xiang-liang-pian-yi-zhi" id="huo-qu-dui-chen-jia-jie-mi-chu-shi-hua-xiang-liang-pian-yi-zhi"></a>

The application obtains the offset value of the symmetric encryption and decryption initialization vector according to the context of symmetric encryption and decryption, as shown below:

```c
void rt_hwcrypto_symmetric_get_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t *iv_off);copymistakeCopy Success
```

| **parameter** | **describe**                         |
| ------------- | ------------------------------------ |
| ctx           | Context                              |
| iv\_off       | Initialization vector offset pointer |
| **return**    | ——                                   |

#### [Copy the symmetric encryption and decryption context](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e5%a4%8d%e5%88%b6%e5%af%b9%e7%a7%b0%e5%8a%a0%e8%a7%a3%e5%af%86%e4%b8%8a%e4%b8%8b%e6%96%87) <a href="#fu-zhi-dui-chen-jia-jie-mi-shang-xia-wen" id="fu-zhi-dui-chen-jia-jie-mi-shang-xia-wen"></a>

The application copies the source symmetric encryption and decryption context to the destination context as shown below:

```c
rt_err_t rt_hwcrypto_symmetric_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src);copymistakeCopy Success
```

| **parameter** | **describe**       |
| ------------- | ------------------ |
| of the        | Target context     |
| src           | Source context     |
| **return**    | ——                 |
| RT\_EOK       | Set up for success |
| other         | fail               |

#### [Reset symmetric encryption and decryption context](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e9%87%8d%e7%bd%ae%e5%af%b9%e7%a7%b0%e5%8a%a0%e8%a7%a3%e5%af%86%e4%b8%8a%e4%b8%8b%e6%96%87) <a href="#zhong-zhi-dui-chen-jia-jie-mi-shang-xia-wen" id="zhong-zhi-dui-chen-jia-jie-mi-shang-xia-wen"></a>

The application resets the context based on the symmetric encryption and decryption context as follows:

```c
void rt_hwcrypto_symmetric_reset(struct rt_hwcrypto_ctx *ctx);copymistakeCopy Success
```

| **parameter** | **describe** |
| ------------- | ------------ |
| of the        | Context      |
| **return**    | ——           |

#### [Set the encryption and decryption type](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%be%e7%bd%ae%e5%8a%a0%e8%a7%a3%e5%af%86%e7%b1%bb%e5%9e%8b) <a href="#she-zhi-jia-jie-mi-lei-xing" id="she-zhi-jia-jie-mi-lei-xing"></a>

The application sets encryption or decryption based on the context of symmetric encryption and decryption, as shown below:

```c
rt_err_t rt_hwcrypto_symmetric_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type);copymistakeCopy Success
```

| **parameter** | **describe**                   |
| ------------- | ------------------------------ |
| ctx           | Context                        |
| type          | Encryption and decryption type |
| **return**    | ——                             |
| RT\_EOK       | Set up for success             |
| other         | fail                           |

* For common encryption and decryption types, refer to the type introduction in Creating Symmetric Encryption and Decryption Contexts.

AES-CBC is used for encryption. The application examples are as follows:

```c
/* 加密密钥 */
static const rt_uint8_t key[16] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};

static void hw_aes_cbc(const rt_uint8_t in[32], rt_uint8_t out[32], hwcrypto_mode mode);

int main(void)
{
    rt_uint8_t buf_in[32];
    rt_uint8_t buf_out[32];
    int i;

    /* 填充测试数据 */
    for (i = 0; i < sizeof(buf_in); i++)
    {
        buf_in[i] = (rt_uint8_t)i;
    }

    memset(buf_out, 0, sizeof(buf_out));
    /* 对测试数据进行加密 */
    hw_aes_cbc(buf_in, buf_out, HWCRYPTO_MODE_ENCRYPT);
}

static void hw_aes_cbc(const rt_uint8_t in[32], rt_uint8_t out[32], hwcrypto_mode mode)
{
    struct rt_hwcrypto_ctx *ctx;

    /* 创建一个 AES-CBC 模式的上下文 */
    ctx = rt_hwcrypto_symmetric_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_AES_CBC);
    if (ctx == RT_NULL)
    {
        LOG_E("create AES-CBC context err!");
        return;
    }
    /* 设置 AES-CBC 加密密钥 */
    rt_hwcrypto_symmetric_setkey(ctx, key, 128);
    /* 执行 AES-CBC 加密/解密 */
    rt_hwcrypto_symmetric_crypt(ctx, mode, 32, in, out);
    /* 删除上下文，释放资源 */
    rt_hwcrypto_symmetric_destroy(ctx);
}
copymistakeCopy Success
```

### [gcm message authentication](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=gcm-%e6%b6%88%e6%81%af%e8%ae%a4%e8%af%81) <a href="#gcm-xiao-xi-ren-zheng" id="gcm-xiao-xi-ren-zheng"></a>

GCM message authentication can provide encryption and integrity verification of messages, and can also verify the authenticity of other attached messages.

#### [Access gcm device](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%bf%e9%97%ae-gcm-%e8%ae%be%e5%a4%87) <a href="#fang-wen-gcm-she-bei" id="fang-wen-gcm-she-bei"></a>

The application accesses the GCM algorithm device hardware through the GCM device management interface provided by RT-Thread. The relevant interface is as follows:

| function                        | describe                               |
| ------------------------------- | -------------------------------------- |
| rt\_hwcrypto\_gcm\_create()     | Creating a Context                     |
| rt\_hwcrypto\_gcm\_destroy()    | Release context                        |
| rt\_hwcrypto\_gcm\_start()      | Passing in additional value            |
| rt\_hwcrypto\_gcm\_finish()     | Generate a message authentication code |
| rt\_hwcrypto\_gcm\_crypt()      | Encryption and decryption              |
| rt\_hwcrypto\_gcm\_setkey()     | Setting the key                        |
| rt\_hwcrypto\_gcm\_getkey()     | Get the key                            |
| rt\_hwcrypto\_gcm\_setiv()      | Setting the Initialization Vector      |
| rt\_hwcrypto\_gcm\_getiv()      | Get the initialization vector          |
| rt\_hwcrypto\_gcm\_set\_ivoff() | Set the initialization vector offset   |
| rt\_hwcrypto\_gcm\_get\_ivoff() | Get the initialization vector offset   |
| rt\_hwcrypto\_gcm\_cpy()        | Copy context                           |
| rt\_hwcrypto\_gcm\_reset()      | Reset Context                          |

#### [Create a gcm context](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e5%88%9b%e5%bb%ba-gcm-%e4%b8%8a%e4%b8%8b%e6%96%87) <a href="#chuang-jian-gcm-shang-xia-wen" id="chuang-jian-gcm-shang-xia-wen"></a>

The application creates a symmetric encryption and decryption context based on the handle of the gcm message authentication, as shown below:

```c
struct rt_hwcrypto_ctx *rt_hwcrypto_gcm_create(struct rt_hwcrypto_device *device,
                                               hwcrypto_type crypt_type);copymistakeCopy Success
```

| **parameter** | **describe**                             |
| ------------- | ---------------------------------------- |
| device        | Encryption and decryption device handle  |
| crypt\_type   | Encryption and decryption algorithm type |
| **return**    | ——                                       |
| NULL          | fail                                     |
| other         | Device Object                            |

The common types of gcm are as follows

```c
    /* symmetric Type */
    HWCRYPTO_TYPE_AES     = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< AES */
    HWCRYPTO_TYPE_DES     = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< DES */
    HWCRYPTO_TYPE_3DES    = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< 3DES */
    HWCRYPTO_TYPE_RC4     = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< RC4 */
    HWCRYPTO_TYPE_GCM     = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16,  /**< GCM */

    /* AES Subtype */
    HWCRYPTO_TYPE_AES_ECB = HWCRYPTO_TYPE_AES | (0x01 << 8),
    HWCRYPTO_TYPE_AES_CBC = HWCRYPTO_TYPE_AES | (0x02 << 8),
    HWCRYPTO_TYPE_AES_CFB = HWCRYPTO_TYPE_AES | (0x03 << 8),
    HWCRYPTO_TYPE_AES_CTR = HWCRYPTO_TYPE_AES | (0x04 << 8),
    HWCRYPTO_TYPE_AES_OFB = HWCRYPTO_TYPE_AES | (0x05 << 8),

    /* DES Subtype */
    HWCRYPTO_TYPE_DES_ECB = HWCRYPTO_TYPE_DES | (0x01 << 8),
    HWCRYPTO_TYPE_DES_CBC = HWCRYPTO_TYPE_DES | (0x02 << 8),

    /* 3DES Subtype */
    HWCRYPTO_TYPE_3DES_ECB = HWCRYPTO_TYPE_3DES | (0x01 << 8),
    HWCRYPTO_TYPE_3DES_CBC = HWCRYPTO_TYPE_3DES | (0x02 << 8),copymistakeCopy Success
```

#### [Release context](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e9%87%8a%e6%94%be%e4%b8%8a%e4%b8%8b%e6%96%87-2) <a href="#shi-fang-shang-xia-wen-2" id="shi-fang-shang-xia-wen-2"></a>

The application deletes the context and releases resources based on the gcm context, as shown below:

```c
void rt_hwcrypto_gcm_destroy(struct rt_hwcrypto_ctx *ctx);copymistakeCopy Success
```

| **parameter** | **describe** |
| ------------- | ------------ |
| ctx           | Context      |
| **return**    | ——           |

#### [Passing in additional value](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e4%bc%a0%e5%85%a5%e9%99%84%e5%8a%a0%e5%80%bc) <a href="#chuan-ru-fu-jia-zhi" id="chuan-ru-fu-jia-zhi"></a>

The application passes in the initial value of the additional value for encryption according to the context of gcm, as shown below:

```c
rt_err_t rt_hwcrypto_gcm_start(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *add,
                               rt_size_t add_len);copymistakeCopy Success
```

| **parameter** | **describe**              |
| ------------- | ------------------------- |
| ctx           | Context                   |
| add           | Additional Message        |
| add\_len      | Additional message length |
| **return**    | ——                        |
| RT\_EOK       | success                   |
| other         | fail                      |

#### [Generate a message authentication code](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e7%94%9f%e6%88%90%e6%b6%88%e6%81%af%e8%ae%a4%e8%af%81%e7%a0%81) <a href="#sheng-cheng-xiao-xi-ren-zheng-ma" id="sheng-cheng-xiao-xi-ren-zheng-ma"></a>

After encrypting the data according to the context of GCM, the application outputs the tag value and length as a verification of integrity and authenticity, as shown below:

```c
rt_err_t rt_hwcrypto_gcm_finish(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *tag, rt_size_t tag_len);copymistakeCopy Success
```

| **parameter** | **describe**                       |
| ------------- | ---------------------------------- |
| ctx           | Context                            |
| tag           | Message Authentication Code        |
| tag\_len      | Message authentication code length |
| **return**    | ——                                 |
| RT\_EOK       | success                            |
| other         | fail                               |

#### [Encryption and decryption](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%bf%9b%e8%a1%8c%e5%8a%a0%e8%a7%a3%e5%af%86) <a href="#jin-xing-jia-jie-mi" id="jin-xing-jia-jie-mi"></a>

The application encrypts the data according to the context of GCM, encryption and decryption mode, data length and input data, and then outputs the data buffer as shown below:

```c
rt_err_t rt_hwcrypto_gcm_crypt(struct rt_hwcrypto_ctx *ctx, hwcrypto_mode mode,
                               rt_size_t length, const rt_uint8_t *in, rt_uint8_t *out);copymistakeCopy Success
```

| **parameter** | **describe**                   |
| ------------- | ------------------------------ |
| ctx           | Context                        |
| mode          | Encryption and decryption mode |
| length        | Input data length              |
| in            | Input Data                     |
| out           | Output Data                    |
| **return**    | ——                             |
| RT\_EOK       | success                        |
| other         | fail                           |

#### [Setting the key](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%be%e7%bd%ae%e5%af%86%e9%92%a5) <a href="#she-zhi-mi-yao" id="she-zhi-mi-yao"></a>

The application sets the key according to the gcm context, encryption and decryption key and length, as shown below:

```c
rt_err_t rt_hwcrypto_gcm_setkey(struct rt_hwcrypto_ctx *ctx,
                                const rt_uint8_t *key, rt_uint32_t bitlen);copymistakeCopy Success
```

| **parameter** | **describe** |
| ------------- | ------------ |
| ctx           | Context      |
| key           | Key          |
| Bitlen        | Key length   |
| **return**    | ——           |
| RT\_EOK       | success      |
| other         | fail         |

#### [Get the key](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%8e%b7%e5%8f%96%e5%af%86%e9%92%a5-1) <a href="#huo-qu-mi-yao-1" id="huo-qu-mi-yao-1"></a>

The application obtains the key based on the gcm context, encryption and decryption key and length, as shown below:

```c
rt_err_t rt_hwcrypto_gcm_getkey(struct rt_hwcrypto_ctx *ctx,
                                rt_uint8_t *key, rt_uint32_t bitlen);copymistakeCopy Success
```

| **parameter** | **describe** |
| ------------- | ------------ |
| ctx           | Context      |
| key           | Key          |
| Bitlen        | Key length   |
| **return**    | ——           |
| RT\_EOK       | success      |
| other         | fail         |

#### [Setting the Initialization Vector](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%be%e7%bd%ae%e5%88%9d%e5%a7%8b%e5%8c%96%e5%90%91%e9%87%8f) <a href="#she-zhi-chu-shi-hua-xiang-liang" id="she-zhi-chu-shi-hua-xiang-liang"></a>

The application sets the initialization vector according to the gcm context, initialization vector and length, as shown below:

```c
rt_err_t rt_hwcrypto_gcm_setiv(struct rt_hwcrypto_ctx *ctx,
                               const rt_uint8_t *iv, rt_size_t len);copymistakeCopy Success
```

| **parameter** | **describe**                 |
| ------------- | ---------------------------- |
| ctx           | Context                      |
| iv            | Initialization Vector        |
| only          | Initialization vector length |
| **return**    | ——                           |
| RT\_EOK       | success                      |
| other         | fail                         |

#### [Get the initialization vector](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%8e%b7%e5%8f%96%e5%88%9d%e5%a7%8b%e5%8c%96%e5%90%91%e9%87%8f) <a href="#huo-qu-chu-shi-hua-xiang-liang" id="huo-qu-chu-shi-hua-xiang-liang"></a>

The application obtains the initialization vector based on the gcm context, initialization vector and length, as shown below:

```c
rt_err_t rt_hwcrypto_gcm_getiv(struct rt_hwcrypto_ctx *ctx,
                               rt_uint8_t *iv, rt_size_t len);copymistakeCopy Success
```

| **parameter** | **describe**                 |
| ------------- | ---------------------------- |
| ctx           | Context                      |
| iv            | Initialization Vector        |
| only          | Initialization vector length |
| **return**    | ——                           |
| RT\_EOK       | success                      |
| other         | fail                         |

#### [Set the initialization vector offset](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%be%e7%bd%ae%e5%88%9d%e5%a7%8b%e5%8c%96%e5%90%91%e9%87%8f%e5%81%8f%e7%a7%bb) <a href="#she-zhi-chu-shi-hua-xiang-liang-pian-yi" id="she-zhi-chu-shi-hua-xiang-liang-pian-yi"></a>

The application sets the initialization vector offset according to the context of gcm, as shown below:

```c
void rt_hwcrypto_gcm_set_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t iv_off);copymistakeCopy Success
```

| **parameter** | **describe**                 |
| ------------- | ---------------------------- |
| ctx           | Context                      |
| iv\_off       | Initialization vector offset |
| **return**    | ——                           |

#### [Get the initialization vector offset](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%8e%b7%e5%8f%96%e5%88%9d%e5%a7%8b%e5%8c%96%e5%90%91%e9%87%8f%e5%81%8f%e7%a7%bb) <a href="#huo-qu-chu-shi-hua-xiang-liang-pian-yi" id="huo-qu-chu-shi-hua-xiang-liang-pian-yi"></a>

The application obtains the initialization vector offset based on the gcm context and initialization vector offset, as shown below:

```c
void rt_hwcrypto_gcm_get_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t iv_off);copymistakeCopy Success
```

| **parameter** | **describe**                 |
| ------------- | ---------------------------- |
| ctx           | Context                      |
| iv\_off       | Initialization vector offset |
| **return**    | ——                           |

#### [Copy context](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e5%a4%8d%e5%88%b6%e4%b8%8a%e4%b8%8b%e6%96%87-1) <a href="#fu-zhi-shang-xia-wen-1" id="fu-zhi-shang-xia-wen-1"></a>

The application copies the gcm context to the target context as follows:

```c
rt_err_t rt_hwcrypto_gcm_cpy(struct rt_hwcrypto_ctx *des,
                             const struct rt_hwcrypto_ctx *src);copymistakeCopy Success
```

| **parameter** | **describe**   |
| ------------- | -------------- |
| of the        | Target context |
| src           | Source context |
| **return**    | ——             |
| RT\_EOK       | success        |
| other         | fail           |

### [CRC redundancy check](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=crc-%e5%86%97%e4%bd%99%e6%a0%a1%e9%aa%8c) <a href="#crc-rong-yu-jiao-yan" id="crc-rong-yu-jiao-yan"></a>

Cyclic Redundancy Check (CRC) is a hash function that generates a short fixed-bit check code based on network data packets or computer files. It is mainly used to detect or verify errors that may occur after data transmission or storage. It uses the principle of division and remainder for error detection.

#### [Accessing CRC Devices](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%bf%e9%97%ae-crc-%e8%ae%be%e5%a4%87) <a href="#fang-wen-crc-she-bei" id="fang-wen-crc-she-bei"></a>

The application accesses the CRC algorithm device hardware through the CRC device management interface provided by RT-Thread. The relevant interface is as follows:

| function                     | describe                     |
| ---------------------------- | ---------------------------- |
| rt\_hwcrypto\_crc\_create()  | Create CRC context           |
| rt\_hwcrypto\_crc\_destroy() | Release context              |
| rt\_hwcrypto\_crc\_update()  | Calculate a packet of data   |
| rt\_hwcrypto\_crc\_cfg()     | Set context calculation data |

#### [Create CRC context](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e5%88%9b%e5%bb%ba-crc-%e4%b8%8a%e4%b8%8b%e6%96%87) <a href="#chuang-jian-crc-shang-xia-wen" id="chuang-jian-crc-shang-xia-wen"></a>

The application creates a CRC context based on the handle of the CRC device as follows:

```c
struct rt_hwcrypto_ctx *rt_hwcrypto_crc_create(struct rt_hwcrypto_device *device,
                                               hwcrypto_crc_mode mode);copymistakeCopy Success
```

| **parameter** | **describe**         |
| ------------- | -------------------- |
| device        | Device to be set up  |
| mode          | CRC calculation mode |
| **return**    | ——                   |
| NULL          | fail                 |
| other         | Device Object        |

The commonly used CRC calculation modes are as follows:

```c
typedef enum
{
    HWCRYPTO_CRC_CUSTOM,        /**< Custom CRC mode */
    HWCRYPTO_CRC_CRC8,          /**< poly : 0x07 */
    HWCRYPTO_CRC_CRC16,         /**< poly : 0x8005 */
    HWCRYPTO_CRC_CRC32,         /**< poly : 0x04C11DB7 */
    HWCRYPTO_CRC_CCITT,         /**< poly : 0x1021 */
    HWCRYPTO_CRC_DNP,           /**< poly : 0x3D65 */
} hwcrypto_crc_mode;copymistakeCopy Success
```

These modes correspond to different calculation polynomials, as shown in the notes.

#### [Release context](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e9%87%8a%e6%94%be%e4%b8%8a%e4%b8%8b%e6%96%87-3) <a href="#shi-fang-shang-xia-wen-3" id="shi-fang-shang-xia-wen-3"></a>

The application deletes the context according to the CRC context and releases the resources as follows:

```c
void rt_hwcrypto_crc_destroy(struct rt_hwcrypto_ctx *ctx);copymistakeCopy Success
```

| **parameter** | **describe** |
| ------------- | ------------ |
| ctx           | Context      |
| **return**    | ——           |

#### [Calculate data](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%a1%e7%ae%97%e6%95%b0%e6%8d%ae) <a href="#ji-suan-shu-ju" id="ji-suan-shu-ju"></a>

The application calculates the CRC calculation result based on the CRC context, input data and its length as follows:

```c
rt_uint32_t rt_hwcrypto_crc_update(struct rt_hwcrypto_ctx *ctx,
                                   const rt_uint8_t *input, rt_size_t length);copymistakeCopy Success
```

| **parameter** | **describe**        |
| ------------- | ------------------- |
| ctx           | Context             |
| input         | Input Data          |
| length        | Input data length   |
| **return**    | ——                  |
| uint32\_t     | Calculation results |
| 0             | fail                |

#### [Setting Configuration](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%be%e7%bd%ae%e9%85%8d%e7%bd%ae) <a href="#she-zhi-pei-zhi" id="she-zhi-pei-zhi"></a>

The application releases resources based on the CRC context and configuration information as follows:

```c
void rt_hwcrypto_crc_cfg(struct rt_hwcrypto_ctx *ctx,
                         struct hwcrypto_crc_cfg *cfg);copymistakeCopy Success
```

| **parameter** | **describe**                                       |
| ------------- | -------------------------------------------------- |
| ctx           | Context                                            |
| cfg           | Encryption and decryption configuration parameters |
| **return**    | ——                                                 |

The CRC configuration structure is as follows

```c
struct hwcrypto_crc_cfg
{
    rt_uint32_t last_val;   /**< Last CRC value cache */
    rt_uint32_t poly;       /**< CRC polynomial */
    rt_uint16_t width;      /**< CRC value width */
    rt_uint32_t xorout;     /**< Result XOR Value */
    rt_uint16_t flags;      /**< Input or output data reverse. CRC_FLAG_REFIN or CRC_FLAG_REFOUT */
};copymistakeCopy Success
```

Calculate the data checksum of 0 - 7 and implement the following configuration

```c
    struct hwcrypto_crc_cfg cfg =
    {
        .last_val = 0xFFFFFFFF,
        .poly = 0x04C11DB7,
        .width = 32,
        .xorout = 0x00000000,
        .flags = 0,
    };copymistakeCopy Success
```

To obtain the checksum value, the specific procedure is as follows

```c
int main(void)
{
    rt_uint8_t temp[] = {0,1,2,3,4,5,6,7};
    struct rt_hwcrypto_ctx *ctx;
    rt_uint32_t result = 0;
    struct hwcrypto_crc_cfg cfg =
    {
        .last_val = 0xFFFFFFFF,
        .poly = 0x04C11DB7,
        .width = 32,
        .xorout = 0x00000000,
        .flags = 0,
    };

    /* 创建设备的上下文 */
    ctx = rt_hwcrypto_crc_create(rt_hwcrypto_dev_default(), HWCRYPTO_CRC_CRC32);/* 设置　CRC　配置　*/
    rt_hwcrypto_crc_cfg(ctx, &cfg);
    /* 输入数据，获取其 CRC 计算值 */
    result = rt_hwcrypto_crc_update(ctx, temp, sizeof(temp));
    /* 打印结果 */
    rt_kprintf("result: %x \n", result);
    /* 释放 ctx */
    rt_hwcrypto_crc_destroy(ctx);
}copymistakeCopy Success
```

### [Random Number Generator](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e9%9a%8f%e6%9c%ba%e6%95%b0%e5%8f%91%e7%94%9f%e5%99%a8) <a href="#sui-ji-shu-fa-sheng-qi" id="sui-ji-shu-fa-sheng-qi"></a>

The data generated by the Random Numeral Generator (RNG) has nothing to do with the previous numbers.

#### [Accessing RNG Devices](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%bf%e9%97%ae-rng-%e8%ae%be%e5%a4%87) <a href="#fang-wen-rng-she-bei" id="fang-wen-rng-she-bei"></a>

The application accesses the RNG algorithm device hardware through the RNG device management interface provided by RT-Thread. The relevant interface is as follows:

| function                    | describe                             |
| --------------------------- | ------------------------------------ |
| rt\_hwcrypto\_rng\_update() | Get the default device random number |

#### [Get the default device random number](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%8e%b7%e5%8f%96%e9%bb%98%e8%ae%a4%e8%ae%be%e5%a4%87%e9%9a%8f%e6%9c%ba%e6%95%b0) <a href="#huo-qu-mo-ren-she-bei-sui-ji-shu" id="huo-qu-mo-ren-she-bei-sui-ji-shu"></a>

The application generates random numbers according to the context of the RNG default device as follows:

```c
rt_uint32_t rt_hwcrypto_rng_update(void);copymistakeCopy Success
```

| **parameter** | **describe**             |
| ------------- | ------------------------ |
| **return**    | ——                       |
| rt\_uint32\_t | Random numbers generated |
| other         | fail                     |

For example, to detect random number generation 1000,000 times and count the number of odd and even numbers generated, the code is as follows:

```c
#include <hw_rng.h>

void hw_rng(void)
{
    rt_uint32_t result=0;
    int i, num0=0, num1 =0;
    const int max_test = 1000 * 1000;


    for (i = 0; i < max_test; i++)
    {
        result = rt_hwcrypto_rng_update();
        result%2 ? num1++ : num0++;
    }
    LOG_I(" num1: %d, num0: %d ",num1, num0);
}copymistakeCopy Success
```

### [Large number operations](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e5%a4%a7%e6%95%b0%e8%bf%90%e7%ae%97) <a href="#da-shu-yun-suan" id="da-shu-yun-suan"></a>

Since the basic numeric data types provided by programming languages ​​have a limited range of values ​​and cannot satisfy large-scale high-precision numerical calculations, other methods are needed to achieve high-precision numerical calculations.

#### [Access to a large number of devices](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%ae%bf%e9%97%ae%e5%a4%a7%e6%95%b0%e8%ae%be%e5%a4%87) <a href="#fang-wen-da-shu-she-bei" id="fang-wen-da-shu-she-bei"></a>

The application accesses the big number algorithm device hardware through the big number device management interface provided by RT-Thread. The relevant interface is as follows:

| function                            | describe                              |
| ----------------------------------- | ------------------------------------- |
| rt\_hwcrypto\_bignum\_default()     | Get the default context               |
| rt\_hwcrypto\_bignum\_init()        | Initialize a large number object      |
| rt\_hwcrypto\_bignum\_free()        | Release the big numbers               |
| rt\_hwcrypto\_bignum\_get\_len()    | Get the length of a large number      |
| rt\_hwcrypto\_bignum\_export\_bin() | Output binary data in big-endian mode |
| rt\_hwcrypto\_bignum\_import\_bin() | Input binary in big-endian mode       |
| rt\_hwcrypto\_bignum\_add()         | Adding large numbers                  |
| rt\_hwcrypto\_bignum\_sub()         | Subtracting large numbers             |
| rt\_hwcrypto\_bignum\_mul()         | Multiplying large numbers             |
| rt\_hwcrypto\_bignum\_mulmod        | Modulo the product of large numbers   |
| rt\_hwcrypto\_bignum\_exptmod       | Modulo large number exponentiation    |

#### [Get the default context](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%8e%b7%e5%8f%96%e9%bb%98%e8%ae%a4%e4%b8%8a%e4%b8%8b%e6%96%87) <a href="#huo-qu-mo-ren-shang-xia-wen" id="huo-qu-mo-ren-shang-xia-wen"></a>

The application obtains the default context based on the large number of device handles, as follows:

```c
rt_err_t rt_hwcrypto_bignum_default(struct rt_hwcrypto_device *device);copymistakeCopy Success
```

| **parameter** | **describe**  |
| ------------- | ------------- |
| device        | Device handle |
| **return**    | ——            |
| RT\_EOK       | success       |
| other         | fail          |

#### [Initialize a large number object](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e5%88%9d%e5%a7%8b%e5%8c%96%e5%a4%a7%e6%95%b0%e5%af%b9%e8%b1%a1) <a href="#chu-shi-hua-da-shu-dui-xiang" id="chu-shi-hua-da-shu-dui-xiang"></a>

The application initializes the big number object according to the big number context, as shown below:

```c
void rt_hwcrypto_bignum_init(struct hw_bignum_mpi *n);copymistakeCopy Success
```

| **parameter** | **describe**                     |
| ------------- | -------------------------------- |
| n             | Initialize a large number object |
| **return**    | ——                               |

The structure of a large number object is as follows:

```c
struct hw_bignum_mpi
{
    int sign;            /**< integer sign */
    rt_size_t total;     /**< total of limbs */
    rt_uint8_t *p;       /**< pointer to limbs */
};copymistakeCopy Success
```

#### [Release the big numbers](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e9%87%8a%e6%94%be%e5%a4%a7%e6%95%b0) <a href="#shi-fang-da-shu" id="shi-fang-da-shu"></a>

The application releases a large number of objects as follows:

```c
void rt_hwcrypto_bignum_free(struct hw_bignum_mpi *n);copymistakeCopy Success
```

| **parameter** | **describe**         |
| ------------- | -------------------- |
| n             | Large number objects |
| **return**    | ——                   |

#### [Get the length of a large number](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%8e%b7%e5%8f%96%e5%a4%a7%e6%95%b0%e9%95%bf%e5%ba%a6) <a href="#huo-qu-da-shu-chang-du" id="huo-qu-da-shu-chang-du"></a>

The application obtains the length of a large number as follows:

```c
int rt_hwcrypto_bignum_get_len(const struct hw_bignum_mpi *n);copymistakeCopy Success
```

| **parameter** | **describe**                                          |
| ------------- | ----------------------------------------------------- |
| n             | The large number object whose length will be obtained |
| **return**    | ——                                                    |
| int           | Returns the length of a large number                  |
| other         | fail                                                  |

#### [Output binary numbers in big-endian format](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e4%bb%a5%e5%a4%a7%e7%ab%af%e6%a8%a1%e5%bc%8f%e8%be%93%e5%87%ba%e4%ba%8c%e8%bf%9b%e5%88%b6%e6%95%b0) <a href="#yi-da-duan-mo-shi-shu-chu-er-jin-zhi-shu" id="yi-da-duan-mo-shi-shu-chu-er-jin-zhi-shu"></a>

The application outputs the binary number in big-endian mode according to the large number object and returns the copied length, as shown below:

```c
int rt_hwcrypto_bignum_export_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len);copymistakeCopy Success
```

| **parameter** | **describe**            |
| ------------- | ----------------------- |
| n             | Large number objects    |
| buf           | Data to be output       |
| only          | Data length             |
| **return**    | ——                      |
| int           | Returns the copy length |
| other         | fail                    |

#### [Input binary numbers in big-endian format](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e4%bb%a5%e5%a4%a7%e7%ab%af%e6%a8%a1%e5%bc%8f%e8%be%93%e5%85%a5%e4%ba%8c%e8%bf%9b%e5%88%b6%e6%95%b0) <a href="#yi-da-duan-mo-shi-shu-ru-er-jin-zhi-shu" id="yi-da-duan-mo-shi-shu-ru-er-jin-zhi-shu"></a>

The application inputs a binary number in big-endian mode according to the handle of the large number, as shown below:

```c
rt_err_t rt_hwcrypto_bignum_import_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len);copymistakeCopy Success
```

| **parameter** | **describe**         |
| ------------- | -------------------- |
| n             | Large number objects |
| buf           | Input Data           |
| only          | Data length          |
| **return**    | ——                   |
| RT\_EOK       | success              |
| other         | fail                 |

#### [Adding large numbers](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e5%a4%a7%e6%95%b0%e7%9b%b8%e5%8a%a0) <a href="#da-shu-xiang-jia" id="da-shu-xiang-jia"></a>

The application adds two large number objects and assigns the result to `x`, as shown below

```c
rt_err_t rt_hwcrypto_bignum_add(struct hw_bignum_mpi *x,
                                const struct hw_bignum_mpi *a,
                                const struct hw_bignum_mpi *b);copymistakeCopy Success
```

| **parameter** | **describe** |
| ------------- | ------------ |
| x             | Output       |
| a             | Input Data   |
| b             | Input Data   |
| **return**    | ——           |
| RT\_EOK       | success      |
| other         | fail         |

#### [Subtracting large numbers](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e5%a4%a7%e6%95%b0%e7%9b%b8%e5%87%8f) <a href="#da-shu-xiang-jian" id="da-shu-xiang-jian"></a>

The application subtracts two large number objects and assigns the result to `x`, as shown below

```c
rt_err_t rt_hwcrypto_bignum_sub(struct hw_bignum_mpi *x,
                                const struct hw_bignum_mpi *a,
                                const struct hw_bignum_mpi *b);copymistakeCopy Success
```

| **parameter** | **describe** |
| ------------- | ------------ |
| x             | Output       |
| a             | Input Data   |
| b             | Input Data   |
| **return**    | ——           |
| RT\_EOK       | success      |
| other         | fail         |

#### [Multiplying large numbers](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e5%a4%a7%e6%95%b0%e7%9b%b8%e4%b9%98) <a href="#da-shu-xiang-cheng" id="da-shu-xiang-cheng"></a>

The application multiplies two large number objects and assigns the result to `x`, as shown below

```c
rt_err_t rt_hwcrypto_bignum_mul(struct hw_bignum_mpi *x,
                                const struct hw_bignum_mpi *a,
                                const struct hw_bignum_mpi *b);copymistakeCopy Success
```

| **parameter** | **describe** |
| ------------- | ------------ |
| x             | Output       |
| a             | Input Data   |
| b             | Input Data   |
| **return**    | ——           |
| RT\_EOK       | success      |
| other         | fail         |

#### [Product modulo](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e4%b9%98%e7%a7%af%e5%8f%96%e6%a8%a1) <a href="#cheng-ji-qu-mo" id="cheng-ji-qu-mo"></a>

The application multiplies the large number object modulo the product and assigns the result to `x = a * b (mod c)`, as shown below

```c
rt_err_t rt_hwcrypto_bignum_mulmod(struct hw_bignum_mpi *x,
                                   const struct hw_bignum_mpi *a,
                                   const struct hw_bignum_mpi *b,
                                   const struct hw_bignum_mpi *c);copymistakeCopy Success
```

| **parameter** | **describe** |
| ------------- | ------------ |
| x             | Output       |
| a             | Input Data   |
| b             | Input Data   |
| c             | Input Data   |
| **return**    | ——           |
| RT\_EOK       | success      |
| other         | fail         |

#### [Modulo exponentiation](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e5%b9%82%e8%bf%90%e7%ae%97%e5%8f%96%e6%a8%a1) <a href="#mi-yun-suan-qu-mo" id="mi-yun-suan-qu-mo"></a>

The application performs exponential modulo on the large number object and assigns the result to `x = a ^ b (mod c)`, as shown below

```c
rt_err_t rt_hwcrypto_bignum_exptmod(struct hw_bignum_mpi *x,
                                    const struct hw_bignum_mpi *a,
                                    const struct hw_bignum_mpi *b,
                                    const struct hw_bignum_mpi *c);copymistakeCopy Success
```

| **parameter** | **describe** |
| ------------- | ------------ |
| x             | Output       |
| a             | Input Data   |
| b             | Input Data   |
| c             | Input Data   |
| **return**    | ——           |
| RT\_EOK       | success      |
| other         | fail         |

### [Crypto device usage examples](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=crypto-%e8%ae%be%e5%a4%87%e4%bd%bf%e7%94%a8%e7%a4%ba%e4%be%8b) <a href="#crypto-she-bei-shi-yong-shi-li" id="crypto-she-bei-shi-yong-shi-li"></a>

Usually, the process of using hardware encryption and decryption can be roughly divided into four steps: the first step is to create a context of a specific encryption and decryption type; the second step is to configure the context, such as setting keys and other operations; the third step is to execute the corresponding function and obtain the processed result; the fourth step is to delete the context and release resources.

#### [Sample Code](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e7%a4%ba%e4%be%8b%e4%bb%a3%e7%a0%81) <a href="#shi-li-dai-ma" id="shi-li-dai-ma"></a>

The following code first uses AES-CBC to encrypt the data, and then decrypts the encrypted data. After decryption, the MD5 and SHA1 hash algorithms are used to generate information summaries, and some log information is output at the same time (the specific implementation code of hardware encryption and decryption is below the main() function).

```c

/* 加密密钥 */
static const rt_uint8_t key[16] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};

int main(void)
{
    rt_uint8_t buf_in[32];
    rt_uint8_t buf_out[32];
    int i;

    /* 填充测试数据 */
    for (i = 0; i < sizeof(buf_in); i++)
    {
        buf_in[i] = (rt_uint8_t)i;
    }
    /* 打印填充的数据 */
    LOG_HEX("Data   ", 8, buf_in, sizeof(buf_in));

    memset(buf_out, 0, sizeof(buf_out));
    /* 对测试数据进行加密 */
    hw_aes_cbc(buf_in, buf_out, HWCRYPTO_MODE_ENCRYPT);

    /* 打印加密后的数据 */
    LOG_HEX("AES-enc", 8, buf_out, sizeof(buf_out));

    memset(buf_in, 0, sizeof(buf_in));
    /* 对加密数据进行解密 */
    hw_aes_cbc(buf_out, buf_in, HWCRYPTO_MODE_DECRYPT);

    /* 打印解密后的数据 */
    LOG_HEX("AES-dec", 8, buf_in, sizeof(buf_in));

    memset(buf_out, 0, sizeof(buf_out));
    /* 对测试数据进行 MD5 运算 */
    hw_hash(buf_in, buf_out, HWCRYPTO_TYPE_MD5);

    /* 打印 16 字节长度的 MD5 结果 */
    LOG_HEX("MD5    ", 8, buf_out, 16);

    memset(buf_out, 0, sizeof(buf_out));
    /* 对测试数据进行 SHA1 运算 */
    hw_hash(buf_in, buf_out, HWCRYPTO_TYPE_SHA1);

    /* 打印 20 字节长度的 SHA1 结果 */
    LOG_HEX("SHA1   ", 8, buf_out, 20);

    return 0;
}copymistakeCopy Success
```

**1. AES-CBC encryption and decryption**

```c
static void hw_aes_cbc(const rt_uint8_t in[32], rt_uint8_t out[32], hwcrypto_mode mode)
{
    struct rt_hwcrypto_ctx *ctx;

    /* 创建一个 AES-CBC 模式的上下文 */
    ctx = rt_hwcrypto_symmetric_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_AES_CBC);
    if (ctx == RT_NULL)
    {
        LOG_E("create AES-CBC context err!");
        return;
    }
    /* 设置 AES-CBC 加密密钥 */
    rt_hwcrypto_symmetric_setkey(ctx, key, 128);
    /* 执行 AES-CBC 加密/解密 */
    rt_hwcrypto_symmetric_crypt(ctx, mode, 32, in, out);
    /* 删除上下文，释放资源 */
    rt_hwcrypto_symmetric_destroy(ctx);
}copymistakeCopy Success
```

**2. HASH message summary**

```c
static void hw_hash(const rt_uint8_t in[32], rt_uint8_t out[32], hwcrypto_type type)
{
    struct rt_hwcrypto_ctx *ctx;

    /* 创建一个 SHA1/MD5 类型的上下文 */
    ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), type);
    if (ctx == RT_NULL)
    {
        LOG_E("create hash[%08x] context err!", type);
        return;
    }
    /* 将输入数据进行 hash 运算 */
    rt_hwcrypto_hash_update(ctx, in, 32);
    /* 获得运算结果 */
    rt_hwcrypto_hash_finish(ctx, out, 32);
    /* 删除上下文，释放资源 */
    rt_hwcrypto_hash_destroy(ctx);
}copymistakeCopy Success
```

#### [Operation effect](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/crypto/crypto?id=%e8%bf%90%e8%a1%8c%e6%95%88%e6%9e%9c) <a href="#yun-xing-xiao-guo" id="yun-xing-xiao-guo"></a>

After normal operation, the terminal output information is as follows:

```shell
 \ | /
- RT -     Thread Operating System
 / | \     4.0.1 build Jun  3 2019
 2006 - 2019 Copyright by rt-thread team
D/HEX Data   : 0000-0008: 00 01 02 03 04 05 06 07    ........
               0008-0010: 08 09 0A 0B 0C 0D 0E 0F    ........
               0010-0018: 10 11 12 13 14 15 16 17    ........
               0018-0020: 18 19 1A 1B 1C 1D 1E 1F    ........
D/HEX AES-enc: 0000-0008: 0A 94 0B B5 41 6E F0 45    ....An.E
               0008-0010: F1 C3 94 58 C6 53 EA 5A    ...X.S.Z
               0010-0018: 3C F4 56 B4 CA 48 8A A3    <.V..H..
               0018-0020: 83 C7 9C 98 B3 47 97 CB    .....G..
D/HEX AES-dec: 0000-0008: 00 01 02 03 04 05 06 07    ........
               0008-0010: 08 09 0A 0B 0C 0D 0E 0F    ........
               0010-0018: 10 11 12 13 14 15 16 17    ........
               0018-0020: 18 19 1A 1B 1C 1D 1E 1F    ........
D/HEX MD5    : 0000-0008: B4 FF CB 23 73 7C EC 31    ...#s|.1
               0008-0010: 5A 4A 4D 1A A2 A6 20 CE    ZJM... .
D/HEX SHA1   : 0000-0008: AE 5B D8 EF EA 53 22 C4    .[...S".
               0008-0010: D9 98 6D 06 68 0A 78 13    ..m.h.x.
               0010-0018: 92 F9 A6 42                ...BcopymistakeCopy Success
```

<br>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.aic-eec.com/recommended_by_aic/rt-thread-university-program/devices-and-drivers/crypto-devices.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
