Rockchip · AI & Linux Hub

AI inference

RKNN2 SDK V2.5.0 · Encrypted model deployment

RKNN2 SDK V2.5.0 · Encrypted model deployment · Complete development guide series

· ArmSoM Editorial · Rockchip source documentation · 6 min read

Platform reference: this article follows the Rockchip RKNN2 SDK V2.5.0 Development Guide, including only the SoCs, Linux/Android Runtime and Toolkit combinations stated by the source. Features apply under the chip, SDK, driver and kernel conditions in each section, not automatically to every ArmSoM board. Check the actual ArmSoM BSP, NPU driver, Runtime and model versions before deployment. No ArmSoM hardware validation was performed; logs, performance figures and examples belong to the source.

Sources and proofreading: Chinese follows Chinese V2.5.0 (182 pages); English, Russian and German follow English V2.5.0 (208 pages). Source-specific technical information is retained; older-version content is not presented as new-version fact. Chinese figures come from the Chinese PDF; EN/RU/DE figures come from the English PDF, including separately extracted vector flowcharts. Original section and equation numbers remain. Some source cross-references still use old chapter numbers; dynamic-shape capacity examples contain “1224+140=264”, TP_NORM support statements conflict, and names such as init()/rknn.val_perf() differ from later API descriptions. These source issues are retained and require checking against actual V2.5.0 SDK headers/API references before execution. Code and parameters remain; PDF wrapping and table continuations are repaired.

Rockchip RKNN2 SDK V2.5.0

RKNN2 SDK V2.5.0 · 18/22

1. Software stack and core concepts

2. Environment, versions and board connection

3. Development workflow and interface selection

4. Model conversion and ONNX editing

5. Quantization, hybrid quantization and QAT

6. Inference, accuracy, performance and memory evaluation

7. Runtime lifecycle, layouts and memory

8. Zero-copy interfaces and I/O constraints

9. C API deployment and code generation

10. Toolkit Lite2 Python deployment

11. Matmul API and matrix layouts

12. NPU multicore configuration and performance

13. Dynamic-shape models and deployment

14. Multi-batch inference

15. RK3588/RK3576 NPU SRAM

16. Cache coherency and sparse inference

17. Custom operators: Python and C API

Encrypted model deployment

19. Accuracy troubleshooting

20. Performance analysis and network optimization

21. Memory analysis, sharing and reuse

22. FAQ, error handling and references

4.2.2 Model Encryption Deployment

The RKNN SDK supports offline encryption of RKNN models and decryption at runtime.

Model encryption is only one part of model protection and cannot completely eliminate the risk of cracking; users are advised to avoid direct third-party access to their models as much as possible and to strengthen overall protection at the system level.

Note: The legacy rknn.export_encrypted_rknn_model() / crypt_level scheme is still compatible but no longer recommended. Please use the hybrid encryption scheme described in this section.

This scheme adopts a Hybrid Encryption architecture:

AES-256-CTR: symmetric encryption, used to encrypt the model body (high performance, supports random-access decryption),only support 256bit

RSA-OAEP: asymmetric encryption, used to protect the AES key (secure key distribution)

Key System:

Key Type Owner Purpose
User key AES-256 symmetric key Generated by user Encrypt/decrypt the model body
RK key pair RSA-2048 asymmetric key pair Pre-installed by RK Public key encrypts the user key; the private key built into the chip decrypts the user key

Encrypted file format:

Offset Length Content
0 – 63 64 bytes RKNN file header (plaintext), with the RKCE encryption indicator written at offset 24–47
64+ body AES-256-CTR encrypted model body

The key envelope file ( user_key_iv.enc ) has the format RKKE header (16 bytes) + RSA- OAEP(AES key ‖ AES IV) .

4.2.2.1 ENCRYPTION ON PC/SERVER

For the conversion script, examples, and RK public key, refer to the encryption example in the rknpu2 project: rknpu2/examples/rknn_encrypt_demo .

Use rknn_model_encrypt.py to encrypt a converted .rknn model:

python3 rknn_model_encrypt.py --model model.rknn \
                                --rk-pubkey rk_public_key.pem \
                                [--output-dir ./encrypted] \
                                [--aes-bits 256]

Output files:

File Description
model.rknn The encrypted model (plaintext RKNN header + RKCE indicator + AES-CTR ciphertext)
model_key.bi n The RSA-OAEP encrypted key envelope (with RKKE header), deployed alongside the model

Public key: rk_public_key.pem is provided by Rockchip. After the user key is encrypted by the RK public key, only the RSA private key built into the chip can decrypt it.

4.2.2.2 LOADING ENCRYPTED MODELS ON BOARD

At runtime, the key envelope is passed in via rknn_init_extend.user_key , and rknn_init() performs decryption internally. The subsequent inference flow is identical to that of a plaintext model. An encrypted model can be loaded either from a file path (size set to 0) or as an in- memory buffer.

#include "rknn_api.h"

/* 1. Load the key envelope into memory */
size_t key_env_size = 0;
void* key_env = load_file("model_key.bin", &key_env_size);
if (!key_env) {
    printf("load key envelope failed!\n");
    return -1;
}

/* 2. Pass the key envelope via rknn_init_extend.user_key */
rknn_init_extend init_ext;
rknn_decrypt_key_mem key_mem;
memset(&init_ext, 0, sizeof(rknn_init_extend));
key_mem.key_data = key_env;
key_mem.key_size = (uint32_t)key_env_size;
init_ext.user_key = &key_mem;

/* 3. rknn_init decrypts internally; subsequent usage is the same as a plaintext
model */
rknn_context ctx = 0;
int ret = rknn_init(&ctx, (void*)"model.rknn", 0, 0, &init_ext);
if (ret < 0) {
    if (ret == RKNN_ERR_KEY_INVALID)
        printf("key envelope invalid / RSA unwrap failed\n");
    else if (ret == RKNN_ERR_DECRYPT_FAILED)
        printf("AES-CTR model body decryption failed\n");
    else if (ret == RKNN_ERR_SOC_BIND_FAILED)
        printf("current SoC is not in the bound platform list\n");
    memset(key_env, 0, key_env_size);
    free(key_env);
    return -1;
}

/* 4. The user-side key memory can be released after rknn_init returns */
memset(key_env, 0, key_env_size);
free(key_env);

/* 5. Proceed with the normal inference flow: rknn_query / rknn_inputs_set /
rknn_run / ... */

Memory ownership: The rknn_decrypt_key_mem structure and the buffer pointed to by key_data are owned by the caller. The runtime copies the key envelope inside rknn_init() , so the caller can release it after rknn_init() returns. It is recommended to zero out the key memory ( memset to 0) before releasing it to reduce the risk of key leakage.

Supported platforms: RK3562/RK3566/RK3568/RK3576/RK3588/RV1126B/RV1106/RV1103B

4.2.2.3 COMPATIBILITY OF ENCRYPTED MODELS WITH EXTERNAL MEMORY ALLOCATION/REUSE

When initializing the context, encrypted models are only compatible with Internal memory reuse (external allocation of Internal memory): initialize with the RKNN_FLAG_INTERNAL_ALLOC_OUTSIDE flag and set the Internal memory through rknn_set_internal_mem() . Multiple models can reuse the same block of Internal memory. For details, see the Internal Memory Reuse section in Chapter 5.3.3.

Encrypted models are not compatible with the following features:

Weight sharing: initialization with the RKNN_FLAG_SHARE_WEIGHT_MEM flag is not supported.

External allocation of weights: setting external weight memory through rknn_set_weight_mem() is not supported.

Context reuse: reuse of contexts through the rknn_dup_context() interface is not supported.

Explore this topic → · Learning paths →