Asymmetric Crypto Engine
Introduction
The Asymmetric Crypto Engine (PKE) is a dedicated hardware acceleration unit within the SoC for handling public-key cryptographic operations. Compared with software implementations, the hardware acceleration engine can significantly improve the execution efficiency of asymmetric cryptographic algorithms while protecting key security through a physical isolation mechanism, playing an important role in IoT security systems.
Application Background
In IoT device security scenarios, asymmetric cryptographic algorithms are widely used in critical security processes such as digital signatures, key exchange, and identity authentication. However, such algorithms involve a large number of complex mathematical operations (e.g., large-number modular exponentiation and elliptic curve point multiplication). If implemented entirely in software, they consume significant CPU resources with low execution efficiency. The Asymmetric Crypto Engine implements these core operations through dedicated hardware circuits, greatly improving operation speed while ensuring security.
Working Principle
The Asymmetric Crypto Engine connects to the CPU through the APB bus and internally contains dedicated computation units and storage units. When the application layer needs to perform an asymmetric cryptographic operation, the CPU writes the operation parameters into the engine’s registers and memory area, configures the control register to start the operation, and the engine hardware automatically completes the core cryptographic operation and returns the result. The entire process is transparent to the upper-layer application, and the user can complete the operation through APIs.
Security Features
The Asymmetric Crypto Engine fully considers security protection requirements in its architecture design:
Physical isolation: The engine’s internal storage unit is isolated from the system bus, preventing keys from being stolen by bus sniffing attacks.
OTP key support: Supports pre-burning private keys into the OTP (One Time Programmable) region. The OTP key is directly connected to the engine and cannot be read or tampered with externally.
Side-channel attack protection: Some chip models support DPA (Differential Power Analysis), SPA (Simple Power Analysis), and Timing Attack protection.
TrustZone support: Some chip models support ARM TrustZone technology and can automatically identify the CPU’s secure/non-secure access state.
Advantages
Compared with a pure software implementation, the Asymmetric Crypto Engine offers the following advantages:
High performance: Hardware acceleration significantly shortens operation time and reduces CPU usage.
Low power consumption: Dedicated hardware circuits consume less power than running software algorithms on a general-purpose CPU.
High security: The physical isolation mechanism and OTP key storage effectively prevent key leakage.
Ease of use: Provides well-encapsulated API interfaces, so users do not need to be concerned with low-level hardware details.
Functional Architecture
The following lists the functional specifications of the Asymmetric Crypto Engine by chip series, including the basic functions.
Not supported.
Basic Functions:
Key Generation:
Generate public and private keys using the mathematical properties of elliptic curves.
Digital Signature:
Supported signature algorithm: ECDSA
ECC operation curve support:
Prime field curves: 192-256 bits
Montgomery Curves: Curve25519
Key Exchange: Supports ECDH.
OTP Key Port (only for ECDSA public key generation/signing)
Physically irreversible writing
Physical architecture isolation (OTP key directly connected to ECC engine, preventing bus sniffing attacks)
Basic Functions:
Key Generation:
Generate public and private keys using the mathematical properties of elliptic curves.
Digital Signature:
Supported signature algorithm: ECDSA
ECC operation curve support:
Prime field curves: 192-256 bits
Montgomery Curves: Curve25519
Key Exchange: Supports ECDH.
OTP Key Port (only for ECDSA public key generation/signing)
Physically irreversible writing
Physical architecture isolation (OTP key directly connected to ECC engine, preventing bus sniffing attacks)
Basic Functions:
Key Generation:
Generate public and private keys using the mathematical properties of elliptic curves.
Digital Signature:
Supported signature algorithm: ECDSA
ECC operation curve support:
Prime field curves: 192-256 bits
Montgomery Curves: Curve25519
Key Exchange: Supports ECDH.
OTP Key Port (only for ECDSA public key generation/signing)
Physically irreversible writing
Physical architecture isolation (OTP key directly connected to ECC engine, preventing bus sniffing attacks)
Basic Functions:
Key Generation:
Generate public and private keys using the mathematical properties of elliptic curves.
Digital Signature:
Supported signature algorithm: ECDSA
ECC operation curve support:
Prime field curves: 192-256 bits
Montgomery Curves: Curve25519
Key Exchange: Supports ECDH.
OTP Key Port (only for ECDSA public key generation/signing)
Physically irreversible writing
Physical architecture isolation (OTP key directly connected to ECC engine, preventing bus sniffing attacks)
Basic Functions:
Key Generation:
ECC key generation: Utilizes the mathematical properties of elliptic curves to generate public and private keys.
Digital Signature:
Supported signature algorithms: ECDSA, EdDSA, and RSA
ECC operation curve support:
Prime field curves: 192~256 bits
Montgomery curves: Curve25519
Edwards curves: Ed25519
RSA 256~3072 bits encryption and decryption
Key Exchange: Supports ECDH.
OTP Key Port (only for ECDSA public key generation/signing)
Physically irreversible writing
Physical architecture isolation (OTP key directly connected to ECC engine, preventing bus sniffing attacks)
The engine supports protection against DPA, SPA, and Timing Attacks. The engine algorithm has been certified by NIST CAVP.
Basic Functions:
Key Generation:
RSA key generation: Includes prime number screening and generation of corresponding public and private key pairs.
ECC key generation: Utilizes the mathematical properties of elliptic curves to generate public and private keys, offering higher key efficiency compared to RSA.
Digital Signature:
Supports various signature algorithms, such as RSA, ECDSA, and EdDSA.
ECC operation curve support:
Prime field curves: 112~512 bits (including SM2)
Binary field curves: 113~512 bits
Montgomery curves: 128~512 bits (including X25519, X448)
Edwards curves: 128~512 bits (including Ed25519, Ed448)
RSA 256~4096 bits encryption and decryption
RSA, ECC key exchange
OTP key (only for ECDSA public key generation/signing)
Security Architecture:
The Asymmetric Crypto Engine supports TrustZone technology and can automatically identify whether the CPU access is in Secure or Non-secure state. It incorporates a hardware mutex lock mechanism, meaning the CPU must first obtain this mutex lock before each operation; otherwise, it cannot access the hardware registers.
When the Secure CPU holds the lock, all Non-secure access is blocked. Only after the Secure CPU releases the lock can the Non-secure CPU regain access. Conversely, if a Non-secure CPU holds the lock, the Secure CPU can configure a dedicated preemption register to forcibly release the Non-secure lock and reset the engine, thereby immediately gaining control of the engine.
Additionally, each time the lock is released, the engine automatically clears sensitive information from the hardware and register states, ensuring no information leakage occurs.
The engine supports protection against DPA, SPA, and Timing Attacks. The engine algorithm has been certified by NIST CAVP.
Basic Functions:
Key Generation:
RSA key generation: Includes prime number screening and generation of corresponding public and private key pairs.
ECC key generation: Utilizes the mathematical properties of elliptic curves to generate public and private keys, offering higher key efficiency compared to RSA.
Digital Signature:
Supports various signature algorithms, such as RSA, ECDSA, and EdDSA.
ECC operation curve support:
Prime field curves: 112~512 bits (including SM2)
Montgomery curves: 128~512 bits (including X25519, X448)
Edwards curves: 128~512 bits (including Ed25519, Ed448)
RSA 256~4096 bits encryption and decryption
RSA, ECC key exchange
OTP key (only for ECDSA public key generation/signing)
Security Architecture:
The Asymmetric Crypto Engine supports TrustZone technology and can automatically identify whether the CPU access is in Secure or Non-secure state. It incorporates a hardware mutex lock mechanism, meaning the CPU must first obtain this mutex lock before each operation; otherwise, it cannot access the hardware registers.
When the Secure CPU holds the lock, all Non-secure access is blocked. Only after the Secure CPU releases the lock can the Non-secure CPU regain access. Conversely, if a Non-secure CPU holds the lock, the Secure CPU can configure a dedicated preemption register to forcibly release the Non-secure lock and reset the engine, thereby immediately gaining control of the engine.
Additionally, each time the lock is released, the engine automatically clears sensitive information from the hardware and register states, ensuring no information leakage occurs.
The engine supports protection against DPA, SPA, and Timing Attacks. The engine algorithm has been certified by NIST CAVP.
Basic Functions:
Key Generation:
RSA key generation: Includes prime number screening and generation of corresponding public and private key pairs.
ECC key generation: Utilizes the mathematical properties of elliptic curves to generate public and private keys, offering higher key efficiency compared to RSA.
Digital Signature:
Supports various signature algorithms, such as RSA, ECDSA, and EdDSA.
ECC operation curve support:
Prime field curves: 112~512 bits (including SM2)
Binary field curves: 113~512 bits
Montgomery curves: 128~512 bits (including X25519, X448)
Edwards curves: 128~512 bits (including Ed25519, Ed448)
RSA 256~4096 bits encryption and decryption
RSA, ECC key exchange
OTP key (only for ECDSA public key generation/signing)
Security Architecture:
The Asymmetric Crypto Engine supports TrustZone technology and can automatically identify whether the CPU access is in Secure or Non-secure state. It incorporates a hardware mutex lock mechanism, meaning the CPU must first obtain this mutex lock before each operation; otherwise, it cannot access the hardware registers.
When the Secure CPU holds the lock, all Non-secure access is blocked. Only after the Secure CPU releases the lock can the Non-secure CPU regain access. Conversely, if a Non-secure CPU holds the lock, the Secure CPU can configure a dedicated preemption register to forcibly release the Non-secure lock and reset the engine, thereby immediately gaining control of the engine.
Additionally, each time the lock is released, the engine automatically clears sensitive information from the hardware and register states, ensuring no information leakage occurs.
OTP Keys
In addition to software keys, the engine also supports pre-burning private keys into the OTP region. The OTP key is directly connected to the engine through a physical isolation mechanism and cannot be read or tampered with externally. It is the recommended solution for protecting core private keys in production environments.
Not supported.
The Asymmetric Crypto Engine’s OTP key only supports ECDSA public key generation and signing. The OTP key is directly connected to the engine and uses a physical isolation mechanism to prevent the key from being stolen by bus sniffing attacks.
The engine can obtain the private key in two ways:
Software key: The user passes the private key to the API, which writes it into the engine register.
OTP key: The engine automatically reads the pre-burned private key from the OTP region.
The OTP region can store two private keys for ECDSA use, accessible only through engine triggering and cannot be read or tampered with externally. Before using an OTP key, the private key must first be burned to the specified OTP address.
OTP key configuration is as follows:
OTP Key |
Address |
Size bits |
Default Value |
Description |
|---|---|---|---|---|
ECDSA_PRI_KEY1 |
Physical mapping 0x280 |
256 |
0xFF |
If OTPKEY=1, load this key to ECDSA engine as private key |
ECDSA_PRI_KEY2 |
Physical mapping 0x2A0 |
256 |
0xFF |
If OTPKEY=2, load this key to ECDSA engine as private key |
ECDSA_PRI_KEY1_Read_Protection |
Physical mapping 0x366[2] |
1 |
1 |
0: Enable ECDSA Key1 read protection, prohibit key reading 1: Disable ECDSA Key1 read protection |
ECDSA_PRI_KEY1_Write_Protection |
Physical mapping 0x366[3] |
1 |
1 |
0: Enable ECDSA Key1 write protection, prohibit hackers from writing key to all 0s 1: Disable ECDSA Key1 write protection |
ECDSA_PRI_KEY2_Read_Protection |
Physical mapping 0x366[4] |
1 |
1 |
0: Enable ECDSA Key2 read protection, prohibit key reading 1: Disable ECDSA Key2 read protection |
ECDSA_PRI_KEY2_Write_Protection |
Physical mapping 0x366[5] |
1 |
1 |
0: Enable ECDSA Key2 write protection, prohibit hackers from writing key to all 0s 1: Disable ECDSA Key2 write protection |
The Asymmetric Crypto Engine’s OTP key only supports ECDSA public key generation and signing. The OTP key is directly connected to the engine and uses a physical isolation mechanism to prevent the key from being stolen by bus sniffing attacks.
The engine can obtain the private key in two ways:
Software key: The user passes the private key to the API, which writes it into the engine register.
OTP key: The engine automatically reads the pre-burned private key from the OTP region.
The OTP region can store two private keys for ECDSA use, accessible only through engine triggering and cannot be read or tampered with externally. Before using an OTP key, the private key must first be burned to the specified OTP address.
OTP key configuration is as follows:
OTP Key |
Address |
Size bits |
Default Value |
Description |
|---|---|---|---|---|
ECDSA_PRI_KEY1 |
Physical mapping 0x280 |
256 |
0xFF |
If OTPKEY=1, load this key to ECDSA engine as private key |
ECDSA_PRI_KEY2 |
Physical mapping 0x2A0 |
256 |
0xFF |
If OTPKEY=2, load this key to ECDSA engine as private key |
ECDSA_PRI_KEY1_Read_Protection |
Physical mapping 0x366[2] |
1 |
1 |
0: Enable ECDSA Key1 read protection, prohibit key reading 1: Disable ECDSA Key1 read protection |
ECDSA_PRI_KEY1_Write_Protection |
Physical mapping 0x366[3] |
1 |
1 |
0: Enable ECDSA Key1 write protection, prohibit hackers from writing key to all 0s 1: Disable ECDSA Key1 write protection |
ECDSA_PRI_KEY2_Read_Protection |
Physical mapping 0x366[4] |
1 |
1 |
0: Enable ECDSA Key2 read protection, prohibit key reading 1: Disable ECDSA Key2 read protection |
ECDSA_PRI_KEY2_Write_Protection |
Physical mapping 0x366[5] |
1 |
1 |
0: Enable ECDSA Key2 write protection, prohibit hackers from writing key to all 0s 1: Disable ECDSA Key2 write protection |
The Asymmetric Crypto Engine’s OTP key only supports ECDSA public key generation and signing. The OTP key is directly connected to the engine and uses a physical isolation mechanism to prevent the key from being stolen by bus sniffing attacks.
The engine can obtain the private key in two ways:
Software key: The user passes the private key to the API, which writes it into the engine register.
OTP key: The engine automatically reads the pre-burned private key from the OTP region.
The OTP region can store two private keys for ECDSA use, accessible only through engine triggering and cannot be read or tampered with externally. Before using an OTP key, the private key must first be burned to the specified OTP address.
OTP key configuration is as follows:
OTP Key |
Address |
Size bits |
Default Value |
Description |
|---|---|---|---|---|
ECDSA_PRI_KEY1 |
Physical mapping 0x280 |
256 |
0xFF |
If OTPKEY=1, load this key to ECDSA engine as private key |
ECDSA_PRI_KEY2 |
Physical mapping 0x2A0 |
256 |
0xFF |
If OTPKEY=2, load this key to ECDSA engine as private key |
ECDSA_PRI_KEY1_Read_Protection |
Physical mapping 0x366[2] |
1 |
1 |
0: Enable ECDSA Key1 read protection, prohibit key reading 1: Disable ECDSA Key1 read protection |
ECDSA_PRI_KEY1_Write_Protection |
Physical mapping 0x366[3] |
1 |
1 |
0: Enable ECDSA Key1 write protection, prohibit hackers from writing key to all 0s 1: Disable ECDSA Key1 write protection |
ECDSA_PRI_KEY2_Read_Protection |
Physical mapping 0x366[4] |
1 |
1 |
0: Enable ECDSA Key2 read protection, prohibit key reading 1: Disable ECDSA Key2 read protection |
ECDSA_PRI_KEY2_Write_Protection |
Physical mapping 0x366[5] |
1 |
1 |
0: Enable ECDSA Key2 write protection, prohibit hackers from writing key to all 0s 1: Disable ECDSA Key2 write protection |
The Asymmetric Crypto Engine’s OTP key only supports ECDSA public key generation and signing. The OTP key is directly connected to the engine and uses a physical isolation mechanism to prevent the key from being stolen by bus sniffing attacks.
The engine can obtain the private key in two ways:
Software key: The user passes the private key to the API, which writes it into the engine register.
OTP key: The engine automatically reads the pre-burned private key from the OTP region.
The OTP region can store two private keys for ECDSA use, accessible only through engine triggering and cannot be read or tampered with externally. Before using an OTP key, the private key must first be burned to the specified OTP address.
OTP key configuration is as follows:
OTP Key |
Address |
Size bits |
Default Value |
Description |
|---|---|---|---|---|
ECDSA_PRI_KEY1 |
Physical mapping 0x280 |
256 |
0xFF |
If OTPKEY=1, load this key to ECDSA engine as private key |
ECDSA_PRI_KEY2 |
Physical mapping 0x2A0 |
256 |
0xFF |
If OTPKEY=2, load this key to ECDSA engine as private key |
ECDSA_PRI_KEY1_Read_Protection |
Physical mapping 0x366[2] |
1 |
1 |
0: Enable ECDSA Key1 read protection, prohibit key reading 1: Disable ECDSA Key1 read protection |
ECDSA_PRI_KEY1_Write_Protection |
Physical mapping 0x366[3] |
1 |
1 |
0: Enable ECDSA Key1 write protection, prohibit hackers from writing key to all 0s 1: Disable ECDSA Key1 write protection |
ECDSA_PRI_KEY2_Read_Protection |
Physical mapping 0x366[4] |
1 |
1 |
0: Enable ECDSA Key2 read protection, prohibit key reading 1: Disable ECDSA Key2 read protection |
ECDSA_PRI_KEY2_Write_Protection |
Physical mapping 0x366[5] |
1 |
1 |
0: Enable ECDSA Key2 write protection, prohibit hackers from writing key to all 0s 1: Disable ECDSA Key2 write protection |
The Asymmetric Crypto Engine’s OTP key only supports ECDSA public key generation and signing. The OTP key is directly connected to the engine and uses a physical isolation mechanism to prevent the key from being stolen by bus sniffing attacks.
The engine can obtain the private key in two ways:
Software key: The user passes the private key to the API, which writes it into the engine register.
OTP key: The engine automatically reads the pre-burned private key from the OTP region.
The OTP region can store two private keys for ECDSA use, accessible only through engine triggering and cannot be read or tampered with externally. Before using an OTP key, the private key must first be burned to the specified OTP address.
OTP key configuration is as follows:
OTP Key |
Address |
Size bits |
Default Value |
Description |
|---|---|---|---|---|
ECDSA_PRI_KEY1 |
Physical mapping 0x280 |
256 |
0xFF |
If OTPKEY=1, load this key to ECDSA engine as private key |
ECDSA_PRI_KEY2 |
Physical mapping 0x2A0 |
256 |
0xFF |
If OTPKEY=2, load this key to ECDSA engine as private key |
ECDSA_PRI_KEY1_Read_Protection |
Physical mapping 0x366[2] |
1 |
1 |
0: Enable ECDSA Key1 read protection, prohibit key reading 1: Disable ECDSA Key1 read protection |
ECDSA_PRI_KEY1_Write_Protection |
Physical mapping 0x366[3] |
1 |
1 |
0: Enable ECDSA Key1 write protection, prohibit hackers from writing the key to all 0s 1: Disable ECDSA Key1 write protection |
ECDSA_PRI_KEY2_Read_Protection |
Physical mapping 0x366[4] |
1 |
1 |
0: Enable ECDSA Key2 read protection, prohibit key reading 1: Disable ECDSA Key2 read protection |
ECDSA_PRI_KEY2_Write_Protection |
Physical mapping 0x366[5] |
1 |
1 |
0: Enable ECDSA Key2 write protection, prohibit hackers from writing the key to all 0s 1: Disable ECDSA Key2 write protection |
The Asymmetric Crypto Engine’s OTP key only supports ECDSA public key generation and signing. The OTP key is directly connected to the engine and uses a physical isolation mechanism to prevent the key from being stolen by bus sniffing attacks.
The engine can obtain the private key in two ways:
Software key: The user passes the private key to the API, which writes it into the engine register.
OTP key: The engine automatically reads the pre-burned private key from the OTP region.
The OTP region can store two private keys, accessible only through engine triggering and cannot be read or tampered with externally. Before using an OTP key, the private key must first be burned to the specified OTP address.
By default, the OTP key can only be accessed by a Secure-state CPU. In Secure state, the pke_ecdsa_share_hw_key API can be called to configure the OTP key as shared or non-shared, allowing Non-secure CPU access.
OTP key configuration is as follows:
Key ID |
Key Type |
Length (bits) |
OTP Address |
Key Usage Permission |
|---|---|---|---|---|
0 |
OTP |
256 |
0x280 |
Secure (default) / Non-secure |
1 |
OTP |
256 |
0x2A0 |
Secure (default) / Non-secure |
The Asymmetric Crypto Engine’s OTP key only supports ECDSA public key generation and signing. The OTP key is directly connected to the engine and uses a physical isolation mechanism to prevent the key from being stolen by bus sniffing attacks.
The engine can obtain the private key in two ways:
Software key: The user passes the private key to the API, which writes it into the engine register.
OTP key: The engine automatically reads the pre-burned private key from the OTP region.
The OTP region can store two private keys, accessible only through engine triggering and cannot be read or tampered with externally. Before using an OTP key, the private key must first be burned to the specified OTP address.
By default, the OTP key can only be accessed by a Secure-state CPU. In Secure state, the pke_ecdsa_share_hw_key API can be called to configure the OTP key as shared or non-shared, allowing Non-secure CPU access.
OTP key configuration is as follows:
Key ID |
Key Type |
Length (bits) |
OTP Address |
Key Usage Permission |
|---|---|---|---|---|
0 |
OTP |
256 |
0x280 |
Secure (default) / Non-secure |
1 |
OTP |
256 |
0x2A0 |
Secure (default) / Non-secure |
The Asymmetric Crypto Engine’s OTP key only supports ECDSA public key generation and signing. The OTP key is directly connected to the engine and uses a physical isolation mechanism to prevent the key from being stolen by bus sniffing attacks.
The engine can obtain the private key in two ways:
Software key: The user passes the private key to the API, which writes it into the engine register.
OTP key: The engine automatically reads the pre-burned private key from the OTP region.
The OTP region can store two private keys, accessible only through engine triggering and cannot be read or tampered with externally. Before using an OTP key, the private key must first be burned to the specified OTP address.
By default, the OTP key can only be accessed by a Secure-state CPU. In Secure state, the pke_ecdsa_share_hw_key API can be called to configure the OTP key as shared or non-shared, allowing Non-secure CPU access.
OTP key configuration is as follows:
Key ID |
Key Type |
Length (bits) |
OTP Address |
Key Usage Permission |
|---|---|---|---|---|
0 |
OTP |
256 |
0x340 |
Secure (default) / Non-secure |
1 |
OTP |
256 |
0x360 |
Secure (default) / Non-secure |
Working Principle
The Asymmetric Crypto Engine connects to the CPU through the APB bus and operates in Slave mode. The engine internally contains computation units, storage units, and control registers. The CPU completes operation parameter configuration and result retrieval by reading and writing these registers.
To ensure concurrency safety in a multitasking environment, the engine has a built-in hardware mutex mechanism. When a Secure-state CPU holds the lock, all Non-secure accesses are blocked; if a Non-secure CPU holds the lock, the Secure CPU can forcibly acquire usage rights through a dedicated preemption register, ensuring priority for secure tasks.
Workflow
The standard operation flow of the engine is as follows:
Acquire the mutex: The CPU acquires the engine’s hardware mutex.
Write operation parameters: Write the algorithm parameters into the engine’s storage unit.
Configure operation mode: Set the control register to select the required operation mode.
Start the operation: Enable the engine to start the computation.
Monitor operation progress: Poll the status register to monitor operation progress.
Retrieve operation result: After detecting the completion flag bit, read the operation result from the storage unit.
Release the mutex: Release the mutex so that other tasks can use the engine.
Exception Handling
The engine provides the following exception handling mechanisms:
Error identification: The status register contains error flag bits; if an error is detected during polling, the process can be terminated immediately.
Error feedback: The API returns predefined error codes (a non-zero value indicates an error, and 0 indicates normal completion).
Usage
After introducing the engine’s working principle and flow, the following describes how to use the engine. The engine provides two usage methods: the low-level direct API and the MbedTLS integrated API.
Development Phase
During the development phase, users typically use software keys for functional verification and debugging:
Select the API type:
Use the low-level API to directly control the engine, which offers more comprehensive functionality but requires an understanding of the engine’s working principle.
Use the MbedTLS integrated API, which is more general but only supports software keys.
Configure the SDK:
Enable the Asymmetric Crypto Engine related options in SDK menuconfig.
Select the supported algorithm curves according to requirements.
Call the API:
Refer to the example code to call the corresponding API to complete key generation, signing, or verification operations.
Production Phase
During the production phase, OTP keys are recommended for higher security:
Generate the key pair:
Generate the public/private key pair during the development phase.
Save the public key for signature verification and the private key for OTP burning.
Burn the OTP key:
Burn the private key to the specified OTP address (see the OTP key table above).
Configure the key read protection/write protection bits.
Warning
The OTP (One Time Programmable) region can be written only once and cannot be erased or revoked. Carefully verify the address and data before executing the write command.
Use the low-level API:
The low-level API must be used when using OTP keys.
The MbedTLS API does not support OTP keys.
API
Whether using software keys or OTP keys, Realtek provides comprehensive API interfaces, so users do not need to be concerned with low-level register operation details.
Raw API
The Raw API provides full control over the engine and supports both software keys and OTP keys:
Key generation API: Generates ECC or RSA key pairs.
Signing API: Uses the private key to digitally sign data.
Verification API: Uses the public key to verify signature validity.
Key exchange API: Performs ECDH key exchange.
OTP key configuration API: Configures the access permissions of OTP keys.
MbedTLS API
To improve compatibility, Realtek has integrated the hardware acceleration engine into the MbedTLS API. Users can use the standard MbedTLS ECDSA/ECDH API, with hardware acceleration automatically invoked underneath. The MbedTLS API only supports software keys, not OTP keys. Due to hardware limitations, MbedTLS support for the SECP521R1 curve has been disabled.
Supported Algorithms and Curves
The algorithm curves supported by each chip are listed below. Common curve parameters are pre-built into the ROM, so users do not need to provide them additionally:
Not supported.
SECP256R1
SECP224R1
SECP192R1
SECP256K1
SECP224K1
SECP192K1
BP256R1
CURVE25519
SECP256R1
SECP224R1
SECP192R1
SECP256K1
SECP224K1
SECP192K1
BP256R1
CURVE25519
SECP256R1
SECP224R1
SECP192R1
SECP256K1
SECP224K1
SECP192K1
BP256R1
CURVE25519
SECP256R1
SECP224R1
SECP192R1
SECP256K1
SECP224K1
SECP192K1
BP256R1
CURVE25519
SECP256R1
SECP224R1
SECP192R1
SECP256K1
SECP224K1
SECP192K1
BP256R1
CURVE25519
ED25519
SECP192R1
SECP224R1
SECP256R1
SECP384R1
BP256R1
BP384R1
BP512R1
CURVE25519
SECP192K1
SECP224K1
SECP256K1
CURVE448
ED25519
ED448
SECP192R1
SECP224R1
SECP256R1
SECP384R1
BP256R1
BP384R1
BP512R1
CURVE25519
SECP192K1
SECP224K1
SECP256K1
CURVE448
ED25519
ED448
SECP192R1
SECP224R1
SECP256R1
SECP384R1
BP256R1
BP384R1
BP512R1
CURVE25519
SECP192K1
SECP224K1
SECP256K1
CURVE448
ED25519
ED448
Raw API
PKE Exported Types
-
enum pke_ecp_curve_id
ECC curve identifier.
Values:
/* Curve not defined. */ PKE_ECP_CURVE_NONE = 0 /* Domain parameters for the 192-bit curve defined by FIPS 186-4 and SEC1. */ PKE_ECP_CURVE_SECP192R1 /* Domain parameters for the 224-bit curve defined by FIPS 186-4 and SEC1. */ PKE_ECP_CURVE_SECP224R1 /* Domain parameters for the 256-bit curve defined by FIPS 186-4 and SEC1. */ PKE_ECP_CURVE_SECP256R1 /* Domain parameters for the 384-bit curve defined by FIPS 186-4 and SEC1. */ PKE_ECP_CURVE_SECP384R1 /* 521-bit curve not supported. */ PKE_ECP_CURVE_NULL /* Domain parameters for 256-bit Brainpool curve. */ PKE_ECP_CURVE_BP256R1 /* Domain parameters for 384-bit Brainpool curve. */ PKE_ECP_CURVE_BP384R1 /* Domain parameters for 512-bit Brainpool curve. */ PKE_ECP_CURVE_BP512R1 /* Domain parameters for Curve25519. */ PKE_ECP_CURVE_CURVE25519 /* Domain parameters for 192-bit "Koblitz" curve. */ PKE_ECP_CURVE_SECP192K1 /* Domain parameters for 224-bit "Koblitz" curve. */ PKE_ECP_CURVE_SECP224K1 /* Domain parameters for 256-bit "Koblitz" curve. */ PKE_ECP_CURVE_SECP256K1 /* Domain parameters for Curve448. */ PKE_ECP_CURVE_CURVE448 /* Supported by default ROM driver. */ PKE_ECP_CURVE_ED25519 /* Not supported by default; the user can add support manually. */ PKE_ECP_CURVE_ED448
-
typedef struct pke_ecp_group pke_ecp_group
PKE ECP Group.
Public Members
-
pke_ecp_curve_id curve_id
value in pke_ecp_curve_id.
-
uint32_t precise_bits
ECC operand precision in bits.
-
uint8_t curve_field
PKE_MODE_MAIN_ECC_PRIME, PKE_MODE_MAIN_ECC_BINARY or PKE_MODE_MAIN_EDWARDS.
-
uint8_t curve_is_Montgomery
1 for Montgomery curve (PKE_MASK_CONTROL_MODE_MAIN must be 2’b11), 0 otherwise.
-
uint8_t A_size
Size of parameter A in byte.
-
uint8_t B_size
Size of parameter B in byte.
-
uint8_t P_size
Size of parameter P in byte.
-
uint8_t N_size
Size of parameter N in byte.
-
uint8_t Gx_size
Size of parameter Gx in byte.
-
uint8_t Gy_size
Size of parameter Gy in byte.
-
uint8_t Gz_size
Size of parameter Gz in bytes.
-
uint8_t *A_p
Pointer to parameter A.
-
uint8_t *B_p
Pointer to parameter B.
-
uint8_t *P_p
Pointer to parameter P.
-
uint8_t *N_p
Pointer to parameter N.
-
uint8_t *Gx_p
Pointer to parameter Gx.
-
uint8_t *Gy_p
Pointer to parameter Gy.
-
uint8_t *Gz_p
Pointer to parameter Gz.
-
pke_ecp_curve_id curve_id
-
typedef struct pke_ecp_point pke_ecp_point
PKE ECP Point.
Public Members
-
uint8_t is_inited
Set to 1 when the point is initialized, 0 otherwise.
-
uint8_t *X_p
The X coordinate of the ECP point.
-
uint8_t X_size
The X coordinate size in byte.
-
uint8_t *Y_p
The Y coordinate of the ECP point.
-
uint8_t Y_size
The Y coordinate size in bytes.
-
uint8_t *Z_p
The Z coordinate of the ECP point.
-
uint8_t Z_size
The Z coordinate size in bytes.
-
uint8_t is_inited
PKE Exported Constants
PKE ECC
/* Max: ECC 512 bits. */
#define PKE_ECC_PARAMETER_SIZE (0x40)
/* ECC Curve parameter Modulus. */
#define PKE_ECC_PARAMETER_ADDR_P ((void *)(PKE_MMEM_BASE + 0x0))
/* ECC Exponent. */
#define PKE_ECC_PARAMETER_ADDR_E ((void *)(PKE_MMEM_BASE + 0x40))
/* ECC Curve parameter a. */
#define PKE_ECC_PARAMETER_ADDR_A ((void *)(PKE_MMEM_BASE + 0x80))
/* ECC Curve parameter b / d. */
#define PKE_ECC_PARAMETER_ADDR_B ((void *)(PKE_MMEM_BASE + 0x100))
/* ECC Curve base point x. */
#define PKE_ECC_PARAMETER_ADDR_G_x ((void *)(PKE_MMEM_BASE + 0x140))
/* ECC Curve base point y. */
#define PKE_ECC_PARAMETER_ADDR_G_y ((void *)(PKE_MMEM_BASE + 0x180))
/* ECC Curve base point z, set to 1. */
#define PKE_ECC_PARAMETER_ADDR_G_z ((void *)(PKE_MMEM_BASE + 0x1C0))
/* ECC Result x. */
#define PKE_ECC_PARAMETER_ADDR_RES_x ((void *)(PKE_TMEM_BASE))
/* ECC Result y. */
#define PKE_ECC_PARAMETER_ADDR_RES_y ((void *)(PKE_TMEM_BASE + 0x40))
/* ECC Curve parameter order. */
#define PKE_ECC_PARAMETER_ADDR_N ((void *)(PKE_MMEM_BASE + 0x400))
PKE ECDSA Private Key Selection
/* Use OTP hardware key port 0 ({hw_key2, hw_key1}, 512-bit). */
#define PKE_ECDSA_PRIV_KEY_HW_0 (0)
/* Use OTP hardware key port 1 ({0, hw_key2}, 512-bit). */
#define PKE_ECDSA_PRIV_KEY_HW_1 (1)
/* Use software-provided ECDSA private key. */
#define PKE_ECDSA_PRIV_KEY_SW (2)
/* Check whether the given ID is a valid ECDSA private key selection. */
#define IS_PKE_ECDSA_PRIV_KEY (((ID) == PKE_ECDSA_PRIV_KEY_HW_0) || \
((ID) == PKE_ECDSA_PRIV_KEY_HW_1) || \
((ID) == PKE_ECDSA_PRIV_KEY_SW))
/* Check whether the given ID selects a secure OTP hardware key. */
#define IS_PKE_ECDSA_SECURE_HW_KEY (((ID) == PKE_ECDSA_PRIV_KEY_HW_0) || \
((ID) == PKE_ECDSA_PRIV_KEY_HW_1))
Not supported.
/* LSYS_PKE_ATTR value: 256-bit OTP hardware key provisioned. */
#define PKE_ECDSA_256BIT_HW_KEY_MASK (2)
/* LSYS_PKE_ATTR value: 384-bit OTP hardware key provisioned. */
#define PKE_ECDSA_384BIT_HW_KEY_MASK (1)
/* LSYS_PKE_ATTR value: no OTP hardware key provisioned. */
#define PKE_ECDSA_NO_HW_KEY_MASK (0)
PKE Engine Memory
/* Base address of PKE main memory (MMEM). */
#define PKE_MMEM_BASE ((int)pke_get_pke_addr() + 0x10000)
/* Base address of PKE temporary memory (TMEM). */
#define PKE_TMEM_BASE ((int)pke_get_pke_addr() + 0x20000)
PKE Error Code
/* Prime check error for modular number. */
#define PKE_STATUS_PRIME_CHK_ERR (0x1)
/* R^2 mod N calculation failed. */
#define PKE_STATUS_R2MOD_N_FAILED (0x2)
/* ECC odd point error (Y coordinate is 0). */
#define PKE_STATUS_ECC_ODD_POINT (0x4)
/* Invalid or unsupported PKE function. */
#define PKE_STATUS_INVALID_FUNCTION (0x7)
/* ECC Z coordinate equals zero. */
#define PKE_STATUS_ECC_Z (0x8)
/* EdDSA point decompression failed. */
#define PKE_STATUS_EDDSA_FAIL (0x9)
/* Modular inverse computation failed. */
#define PKE_STATUS_MOD_INV_FAILED (0x10)
/* RSA input message is larger than modulus N. */
#define PKE_STATUS_RSA_INVALID_MESSAGE (0x20)
/* No valid exponent found. */
#define PKE_STATUS_NO_VALID_EXP (0x40)
PKE Mode
/* ECC prime field operation mode. */
#define PKE_MODE_MAIN_ECC_PRIME (0x0)
/* ECC binary field operation mode. */
#define PKE_MODE_MAIN_ECC_BINARY (0x1)
/* RSA operation mode. */
#define PKE_MODE_MAIN_RSA (0x2)
/* Edwards or Montgomery curve operation mode. */
#define PKE_MODE_MAIN_EDWARDS_MONTGOMERY (0x3)
PKE Other Function ID
/* Clear PKE engine state and abort any ongoing operation. */
#define PKE_FUNCTION_ENTRY_CLEAR (0x0)
/* Modular multiplication: A * B mod N. */
#define PKE_FUNCTION_ENTRY_PUBKEY_MOD_MUL (0x2)
/* Modular addition: A + B mod N. */
#define PKE_FUNCTION_ENTRY_PUBKEY_MOD_ADD (0x3)
/* ECC scalar multiplication with private key: k * P. */
#define PKE_FUNCTION_ENTRY_ECDSA_MUL_PRIVATE (0x4)
/* Compute Montgomery constant R^2 mod N for Montgomery reduction. */
#define PKE_FUNCTION_ENTRY_PUBKEY_R_SQAR (0x5)
/* Compute Montgomery constant -N^{-1} mod R. */
#define PKE_FUNCTION_ENTRY_PUBKEY_N_INV (0x6)
/* Modular inverse: k^{-1} mod N. */
#define PKE_FUNCTION_ENTRY_PUBKEY_K_INV (0x7)
/* ECC point addition: P + Q on the configured curve. */
#define PKE_FUNCTION_ENTRY_PUBKEY_ECC_ADD_POINT (0x8)
/* Copy point P into operand A register for subsequent operations. */
#define PKE_FUNCTION_ENTRY_PUBKEY_SET_A_FROM_P (0xA)
/* Binary field (GF(2^m)) polynomial multiplication. */
#define PKE_FUNCTION_ENTRY_PUBKEY_MOD_MUL_BIN (0xB)
/* Binary field (GF(2^m)) XOR (addition): A XOR B. */
#define PKE_FUNCTION_ENTRY_PUBKEY_MOD_XOR (0xC)
/* Reduction: X mod N. */
#define PKE_FUNCTION_ENTRY_PUBKEY_X_MOD_N (0xE)
/* Modular subtraction: A - B mod N. */
#define PKE_FUNCTION_ENTRY_PUBKEY_MOD_SUB (0xF)
/* Miller-Rabin primality witness test. */
#define PKE_FUNCTION_ENTRY_WITNESS (0x10)
/* Big-number multiplication (no modular reduction). */
#define PKE_FUNCTION_ENTRY_BIG_NUM_MUL (0x12)
/* Compute P * Q for RSA prime pair. */
#define PKE_FUNCTION_ENTRY_PQ_MOD (0x13)
/* Simplified ECDSA key generation (hardware-accelerated). */
#define PKE_FUNCTION_ENTRY_SIMPLIFY_ECDSA_GEN (0x18)
/* Simplified ECDSA signature generation (hardware-accelerated). */
#define PKE_FUNCTION_ENTRY_SIMPLIFY_ECDSA_SIGN (0x19)
/* Simplified ECDSA signature verification (hardware-accelerated). */
#define PKE_FUNCTION_ENTRY_SIMPLIFY_ECDSA_VERIFY (0x1A)
/* Simplified EdDSA key generation (hardware-accelerated). */
#define PKE_FUNCTION_ENTRY_SIMPLIFY_EDDSA_GEN (0x1B)
/* Simplified EdDSA signing step 1: compute nonce point R. */
#define PKE_FUNCTION_ENTRY_SIMPLIFY_EDDSA_SIGN_R (0x1C)
/* Simplified EdDSA signing step 2: compute scalar S. */
#define PKE_FUNCTION_ENTRY_SIMPLIFY_EDDSA_SIGN_S (0x1D)
/* Simplified EdDSA signature verification (hardware-accelerated). */
#define PKE_FUNCTION_ENTRY_SIMPLIFY_EDDSA_VERIFY (0x1E)
/* Check whether a curve ID identifies a Montgomery or Edwards curve (Curve25519, Curve448, Ed25519, Ed448). */
#define PKE_ECC_IS_MONTGOMERY_EDWARDS_CURVE (((CURVE_ID) == PKE_ECP_CURVE_CURVE25519) || \
((CURVE_ID) == PKE_ECP_CURVE_CURVE448) || \
((CURVE_ID) == PKE_ECP_CURVE_ED25519) || \
((CURVE_ID) == PKE_ECP_CURVE_ED448))
PKE RSA
/* Max: RSA-4096. */
#define PKE_RSA_PARAMETER_SIZE (0x200)
/* RSA Modulus. */
#define PKE_RSA_PARAMETER_ADDR_N ((void *)(PKE_MMEM_BASE + 0x0))
/* RSA Exponent. */
#define PKE_RSA_PARAMETER_ADDR_E ((void *)(PKE_MMEM_BASE + 0x200))
/* RSA Message. */
#define PKE_RSA_PARAMETER_ADDR_A ((void *)(PKE_MMEM_BASE + 0x400))
/* RSA Result. */
#define PKE_RSA_PARAMETER_ADDR_RES ((void *)(PKE_TMEM_BASE))
/* Miller-Rabin witness test: modulus N memory address. */
#define PKE_RSA_WITNESS_N ((void *)(PKE_MMEM_BASE + 0x0))
/* Miller-Rabin witness test: base A memory address. */
#define PKE_RSA_WITNESS_A ((void *)(PKE_MMEM_BASE + 0x400))
/* Miller-Rabin witness test: result memory address. */
#define PKE_RSA_WITNESS_RES ((void *)(PKE_TMEM_BASE))
/* RSA prime multiplication: prime factor P memory address. */
#define PKE_RSA_PRIME_MUL_P ((void *)(PKE_MMEM_BASE + 0x0))
/* RSA prime multiplication: prime factor Q memory address. */
#define PKE_RSA_PRIME_MUL_Q ((void *)(PKE_MMEM_BASE + 0x180))
/* RSA prime multiplication: result (P*Q) memory address. */
#define PKE_RSA_PRIME_MUL_RES ((void *)(PKE_TMEM_BASE))
PKE Simplified ECDSA
/* Simplified ECDSA message hash length in bits. */
#define PKE_ECC_TMEM_ADDR_ECDSA_HASH_LEN ((void *)(PKE_TMEM_BASE + 0x7C4))
/* Simplified ECDSA per-signature random nonce (scalar k) for signing. */
#define PKE_ECC_TMEM_ADDR_ECDSA_RAND ((void *)(PKE_TMEM_BASE + 0x2C0))
/* Simplified ECDSA signing result R. */
#define PKE_ECC_TMEM_ADDR_ECDSA_SIGN_R ((void *)(PKE_TMEM_BASE + 0x340))
/* Simplified ECDSA signing result S. */
#define PKE_ECC_TMEM_ADDR_ECDSA_SIGN_S ((void *)(PKE_TMEM_BASE + 0x3C0))
/* Simplified ECDSA public key x. */
#define PKE_ECC_TMEM_ADDR_ECDSA_PUBKEY_x ((void *)(PKE_TMEM_BASE + 0x240))
/* Simplified ECDSA public key y. */
#define PKE_ECC_TMEM_ADDR_ECDSA_PUBKEY_y ((void *)(PKE_TMEM_BASE + 0x280))
/* Simplified ECDSA recovered point rQ used for signature verification. */
#define PKE_ECC_TMEM_ADDR_ECDSA_VERIFY_RQ ((void *)(PKE_TMEM_BASE + 0x540))
PKE Simplified ECDSA EdDSA
/* Function entries. */
#define PKE_ECC_TMEM_FUNCTION_ENTRY ((void *)(PKE_TMEM_BASE + 0x0))
/* Simplified ECDSA/EdDSA curve modulus. */
#define PKE_ECC_TMEM_ADDR_P ((void *)(PKE_TMEM_BASE + 0x80))
/* Simplified ECDSA/EdDSA private key. */
#define PKE_ECC_TMEM_ADDR_E ((void *)(PKE_TMEM_BASE + 0xC0))
/* Simplified ECDSA/EdDSA curve parameter a. */
#define PKE_ECC_TMEM_ADDR_A ((void *)(PKE_TMEM_BASE + 0x100))
/* Simplified ECDSA curve parameter b / d. */
#define PKE_ECC_TMEM_ADDR_B ((void *)(PKE_TMEM_BASE + 0x140))
/* Simplified ECDSA/EdDSA curve base point x. */
#define PKE_ECC_TMEM_ADDR_G_x ((void *)(PKE_TMEM_BASE + 0x180))
/* Simplified ECDSA/EdDSA curve base point y. */
#define PKE_ECC_TMEM_ADDR_G_y ((void *)(PKE_TMEM_BASE + 0x1C0))
/* Simplified ECDSA/EdDSA curve point z, set to 1. */
#define PKE_ECC_TMEM_ADDR_G_z ((void *)(PKE_TMEM_BASE + 0x200))
/* Simplified ECDSA/EdDSA curve order. */
#define PKE_ECC_TMEM_ADDR_N ((void *)(PKE_TMEM_BASE + 0x300))
/* Simplified ECDSA: message hash; Simplified EdDSA: hashed private key. */
#define PKE_ECC_TMEM_ADDR_HASH ((void *)(PKE_TMEM_BASE + 0x380))
PKE Simplified EdDSA
/* Simplified EdDSA encoded public key. */
#define PKE_ECC_TMEM_ADDR_EdDSA_PUBKEY ((void *)(PKE_TMEM_BASE + 0x540))
/* Simplified EdDSA message to be signed. */
#define PKE_ECC_TMEM_ADDR_EdDSA_SIGN_MSG ((void *)(PKE_TMEM_BASE + 0x580))
/* Simplified EdDSA signing result R. */
#define PKE_ECC_TMEM_ADDR_EdDSA_SIGN_R ((void *)(PKE_TMEM_BASE + 0x640))
/* Simplified EdDSA signing result S. */
#define PKE_ECC_TMEM_ADDR_EdDSA_SIGN_S ((void *)(PKE_TMEM_BASE + 0x6C0))
/* Simplified EdDSA message to be verified. */
#define PKE_ECC_TMEM_ADDR_EdDSA_VERIFY_MSG ((void *)(PKE_TMEM_BASE + 0x340))
/* Simplified EdDSA verify B_x value. */
#define PKE_ECC_TMEM_ADDR_EdDSA_VERIFY_B_x ((void *)(PKE_TMEM_BASE + 0x440))
/* Simplified EdDSA verify B_y value. */
#define PKE_ECC_TMEM_ADDR_EdDSA_VERIFY_B_y ((void *)(PKE_TMEM_BASE + 0x480))
/* Simplified EdDSA verification result A_x; if A == B, verification succeeds. */
#define PKE_ECC_TMEM_ADDR_EdDSA_VERIFY_A_x ((void *)(PKE_TMEM_BASE + 0x740))
/* Simplified EdDSA verification result A_y; if A == B, verification succeeds. */
#define PKE_ECC_TMEM_ADDR_EdDSA_VERIFY_A_y ((void *)(PKE_TMEM_BASE + 0x780))
PKE Timeout
/* Mutex acquisition timeout in polling loop iterations. */
#define PKE_MUTEX_TIMEOUT ((u32) 1000000)
/* PKE engine operation timeout in polling loop iterations. */
#define PKE_TIMEOUT_CNT (0x100000)
PKE Exported Functions
-
int pke_ecdsa_genkey(pke_ecp_group *grp, int8_t key_id, uint8_t *pri_key_p, uint8_t pri_key_size, uint8_t *pub_key_x, uint8_t *pub_key_y)
Derive the ECDSA public key from the given private key.
- Parameters:
grp – Pointer to the
pke_ecp_groupstructure.key_id – One of PKE ECDSA Private Key Selection group
pri_key_p – Pointer to the software private key in little-endian format, or NULL when using a hardware OTP key.
pri_key_size – SW key size in byte
pub_key_x – Pointer to the output buffer for the x-coordinate of the public key (little-endian format).
pub_key_y – Pointer to the output buffer for the y-coordinate of the public key (little-endian format).
- Returns:
0 on success, or an error code on failure.
-
void pke_ecdsa_lalu_hash_process(uint8_t *buf_out, uint8_t *hash_in, uint32_t hash_len_byte, uint32_t precise_bit)
Pre-process a hash value for use with the ECDSA PKE engine.
- Parameters:
buf_out – Output buffer for the hash value formatted for the PKE engine.
hash_in – Hash result from a software library or the hardware HMAC engine.
hash_len_byte – HASH length in bytes
precise_bit – Bit-length (precision) of the ECC curve.
-
int pke_ecdsa_read_signature(pke_ecp_group *grp, uint8_t *pub_key_x_p, uint8_t *pub_key_y_p, uint8_t *HASH_p, uint8_t HASH_size_byte, uint8_t *sign_r, uint8_t *sign_s)
Verify an ECDSA signature (r, s) for the given hash using the specified public key and elliptic curve group.
- Parameters:
grp – Pointer to the
pke_ecp_groupstructure.pub_key_x_p – Pointer to the x-coordinate of the public key.
pub_key_y_p – Pointer to the y-coordinate of the public key.
HASH_p – Pointer to the hash of the message whose signature is to be verified.
HASH_size_byte – Size of the hash in bytes.
sign_r – Pointer to the ‘r’ component of the provided signature.
sign_s – Pointer to the ‘s’ component of the provided signature.
- Returns:
Returns RTK_SUCCESS if the signature is valid, or an error code on failure.
Configure the sharing attribute of an OTP hardware key (secure-only or shared with non-secure world).
- Parameters:
key_id – PKE_ECDSA_PRIV_KEY_HW_0 or PKE_ECDSA_PRIV_KEY_HW_1.
is_share – 1 to share the key with the non-secure world, 0 for secure-only access.
- Return values:
RTK_SUCCESS – Key sharing configuration updated successfully.
_ERRNO_CRYPTO_KEY_SECURE_ERR – Called from non-secure context.
-
int pke_ecdsa_write_signature(pke_ecp_group *grp, int8_t key_id, uint8_t *rand_p, uint8_t rand_size, uint8_t *pri_key_p, uint8_t pri_key_size, uint8_t *HASH_p, uint8_t HASH_size_byte, uint8_t *sign_r, uint8_t *sign_s)
Generate an ECDSA signature (r, s) for the provided hash using a specified elliptic curve group.
- Parameters:
grp – Pointer to the
pke_ecp_groupstructure.key_id – One of PKE ECDSA Private Key Selection specifying which private key to use for signing.
rand_p – Pointer to the per-signature random nonce (k), must be cryptographically random and never reused.
rand_size – Size of the random value in bytes.
pri_key_p – Pointer to the software private key used for signing, or NULL when using a hardware OTP key.
pri_key_size – Size of the private key in bytes.
HASH_p – Pointer to the hash of the message to be signed.
HASH_size_byte – Size of the hash in bytes.
sign_r – Pointer to the buffer where the ‘r’ component of the signature will be stored.
sign_s – Pointer to the buffer where the ‘s’ component of the signature will be stored.
- Returns:
Returns 0 on success, or an error code on failure.
-
int pke_ecp_group_init_in_rom(pke_ecp_group *grp, pke_ecp_curve_id curve_id)
Initialize ECC curve parameters.
- Parameters:
grp – Pointer to the
pke_ecp_groupstructure.curve_id – One of pke_ecp_curve_id enum
- Return values:
RTK_SUCCESS – ECC curve parameters initialized successfully.
RTK_FAIL – The specified curve ID is not supported by the ROM code.
-
int pke_eddsa_ed25519_genkey(uint8_t *priv_key_le, uint8_t *pub_key_le)
Derive the Ed25519 public key from an existing private key (seed).
- Parameters:
priv_key_le – Pointer to the input private key (32-byte seed) in little-endian format.
pub_key_le – Pointer to a buffer where the generated public key will be stored. The public key will be in little-endian format.
- Returns:
Returns 0 on successful key pair generation, or an error code on failure.
Note
This function derives the Ed25519 public key from the given private key (seed). The public key is output in little-endian format, which may need to be converted for use with external libraries.
-
int pke_eddsa_ed25519_read_signature(uint8_t *message, size_t msg_len, uint8_t *pub_key_le, uint8_t *sign_r, uint8_t *sign_s)
Verify an Ed25519 digital signature for the given message using the provided public key.
- Parameters:
message – Pointer to the message buffer that was signed.
msg_len – Length of the message in bytes.
pub_key_le – Pointer to the buffer containing the public key in little-endian format. This key is used to verify the authenticity of the signature.
sign_r – Pointer to the buffer containing the R component of the signature.
sign_s – Pointer to the buffer containing the S component of the signature.
- Returns:
Returns 0 if the signature is valid and matches the provided message and public key, or an error code if the verification fails.
Note
This function performs the Ed25519 signature verification process. It checks that the signature (R, S) corresponds to the message under the given public key. Ensure that all input buffers are correctly sized for Ed25519: exactly 32 bytes for the public key, sign_r, and sign_s each.
-
int pke_eddsa_ed25519_write_signature(uint8_t *message, size_t msg_len, uint8_t *priv_key_le, uint8_t *sign_r, uint8_t *sign_s)
Generate an Ed25519 digital signature for the given message using the provided private key and R value.
- Parameters:
message – Pointer to the message buffer that needs to be signed.
msg_len – Length of the message in bytes.
priv_key_le – Pointer to the buffer containing the private key in little-endian format. This key is used in the signature generation.
sign_r – Pointer to the output buffer where the computed R component of the signature will be stored.
sign_s – Pointer to the buffer where the generated S value of the signature will be stored. The buffer should be appropriately sized for the signature component.
- Returns:
Returns 0 on successful signature generation, or an error code on failure.
Note
This function performs the complete Ed25519 signature generation, computing both the R and S components of the signature (R, S). This function computes both the R and S components internally. Both sign_r and sign_s are output buffers and must each be at least 32 bytes. Ensure that the provided buffers are correctly initialized and of sufficient size to prevent any memory issues.
-
int pke_eddsa_genkey(pke_ecp_group *grp, uint8_t *hashed_key_p, uint8_t *pub_key_encode_p)
Generate an encoded public key for use in EdDSA (Edwards-curve Digital Signature Algorithm) given a hashed private key.
- Parameters:
grp – Pointer to the
pke_ecp_groupstructure.hashed_key_p – Pointer to the buffer containing the hashed private key.
pub_key_encode_p – Pointer to the buffer where the encoded public key will be stored.
- Returns:
Returns 0 on success, or an error code on failure.
-
int pke_eddsa_read_signature(pke_ecp_group *grp, uint8_t *pub_key_p, uint8_t *k_buf, uint8_t k_size, uint8_t *sign_r, uint8_t *sign_s)
Verify an EdDSA signature (R, S) using the provided public key and additional buffers.
- Parameters:
grp – Pointer to the
pke_ecp_groupstructure.pub_key_p – Pointer to the buffer containing the public key used for signature verification.
k_buf – Pointer to the buffer containing the pre-computed scalar k = SHA512(R || A || M) used in EdDSA verification.
k_size – Size of the k_buf buffer in bytes.
sign_r – Pointer to the buffer containing the R component of the signature.
sign_s – Pointer to the buffer containing the S component of the signature.
- Returns:
Returns 0 on successful verification, or an error code on failure.
-
void pke_engine_init(void)
Initialize PKE engine.
Enable clock and release reset
Initialize engine memory (MMEM / TMEM) to zero.
Set PKE HW key to secure only
Not supported.
-
int pke_ecdsa_set_hw_key_length(int8_t key_id, uint8_t hw_key_size_byte)
Set the hardware OTP key length mask for PKE ECDSA key selection.
- Parameters:
key_id – PKE_ECDSA_PRIV_KEY_HW_0 or PKE_ECDSA_PRIV_KEY_HW_1
hw_key_size_byte – HW key size in byte
- Return values:
RTK_SUCCESS – Key length mask configured successfully.
_ERRNO_CRYPTO_KEY_SECURE_ERR – Called from non-secure context.