非对称加密引擎

概述

非对称加密引擎(Asymmetric Crypto Engine,简称 PKE)是 SoC 芯片内专门用于处理公钥密码学运算的硬件加速单元。相比软件实现,硬件加速引擎能够显著提升非对称加密算法的执行效率,同时通过物理隔离机制保护密钥安全,在物联网安全系统中具有重要作用。

应用背景

在物联网设备的安全场景中,非对称加密算法被广泛应用于数字签名、密钥交换和身份认证等关键安全流程。然而,这类算法涉及大量复杂数学运算(如大数模幂运算、椭圆曲线点乘运算等),若完全由软件实现,会消耗大量 CPU 资源且执行效率较低。非对称加密引擎通过专用硬件电路实现这些核心运算,可在保证安全性的前提下大幅提升运算速度。

工作原理

非对称加密引擎通过 APB 总线与 CPU 连接,内部包含专门的运算单元和存储单元。当应用层需要执行非对称加密运算时,CPU 将运算参数写入引擎的寄存器和存储区,配置控制寄存器启动运算,引擎硬件自动完成核心密码学运算并返回结果。整个过程对上层应用透明,用户通过 API 即可完成操作。

安全特性

非对称加密引擎在架构设计上充分考虑了安全防护需求:

  • 物理隔离:引擎内部存储单元与系统总线隔离,防止密钥被总线嗅探攻击窃取

  • OTP 密钥支持:支持将私钥预烧录到 OTP(One Time Programmable)区域,OTP 密钥与引擎直连,无法被外部读取或篡改

  • 侧信道攻击防护:部分芯片型号支持 DPA(差分功耗分析)、SPA(简单功耗分析)和 Timing Attack(时序攻击)防护

  • TrustZone 支持:部分芯片型号支持 ARM TrustZone 技术,可自动识别 CPU 的安全/非安全访问状态

方案优点

相比纯软件实现,非对称加密引擎具有以下优势:

  • 高性能:硬件加速可大幅缩短运算时间,减少 CPU 占用

  • 低功耗:专用硬件电路比通用 CPU 运行软件算法功耗更低

  • 高安全性:物理隔离机制和 OTP 密钥存储有效防止密钥泄露

  • 易用性:提供封装良好的 API 接口,用户无需关注底层硬件细节

功能架构

以下按芯片系列列出非对称加密引擎的功能规格,包括基本功能等。

RTL8721Dx:

不支持。

OTP 密钥支持

除软件密钥外,引擎还支持将私钥预烧录到 OTP 区域。OTP 密钥与引擎通过物理隔离机制直连,无法被外部读取或篡改,是生产环境中保护核心私钥的推荐方案。

RTL8721Dx:

不支持。

工作原理

非对称加密引擎通过 APB 总线与 CPU 连接,采用 Slave 模式工作。引擎内部包含运算单元、存储单元和控制寄存器,CPU 通过读写这些寄存器完成运算参数配置和结果获取。

为保障多任务环境下的并发安全,引擎内置硬件互斥锁机制。当 Secure 状态的 CPU 持有锁时,所有 Non-secure 访问均会被阻止;若 Non-secure CPU 持有锁,Secure CPU 可通过专用抢占寄存器强制获取使用权,确保安全任务优先。

工作流程

引擎的标准操作流程如下:

  1. 获取互斥锁:CPU 获取引擎的硬件互斥锁

  2. 写入运算参数:将算法参数写入引擎的存储单元

  3. 配置运算模式:设置控制寄存器选择所需的运算模式

  4. 启动运算:使能引擎开始执行计算

  5. 监测运算进度:轮询状态寄存器监测运算进度

  6. 获取运算结果:检测到结束标志位后,从存储单元读取运算结果

  7. 释放互斥锁:释放互斥锁,使其他任务可以使用引擎

异常处理

引擎具备以下异常处理机制:

  • 错误识别:状态寄存器包含错误标志位,轮询时检测到错误可立即终止流程

  • 错误反馈:API 返回预定义错误码(非零值表示错误,0 表示正常完成)

使用方法

介绍了引擎的工作原理和流程后,以下介绍引擎的具体使用方法。引擎提供了两种使用方式:底层直接 API 和 MbedTLS 集成 API。

开发阶段

在开发阶段,用户通常使用软件密钥进行功能验证和调试:

  1. 选择 API 类型

    • 使用底层 API 直接控制引擎,功能更全面,但需要了解引擎工作原理

    • 使用 MbedTLS 集成 API,接口更通用,但仅支持软件密钥

  2. 配置 SDK

    • 在 SDK menuconfig 中启用非对称加密引擎相关选项

    • 根据需求选择支持的算法曲线

  3. 调用 API

    • 参考示例代码调用相应 API 完成密钥生成、签名或验签操作

生产阶段

在生产阶段,推荐使用 OTP 密钥以获得更高安全性:

  1. 生成密钥对

    • 开发阶段生成公私钥对

    • 保存公钥用于验签,私钥用于 OTP 烧录

  2. 烧录 OTP 密钥

    • 将私钥烧录到 OTP 指定地址(参见上文 OTP 密钥表)

    • 配置密钥读保护/写保护位

    警告

    OTP(One Time Programmable)区域只能写入一次,无法擦除或撤销。请在执行写入命令前,仔细核对地址和数据。

  3. 使用底层 API

    • 使用 OTP 密钥时必须调用底层 API

    • MbedTLS API 不支持 OTP 密钥

API 接口

无论使用软件密钥还是 OTP 密钥,Realtek 都提供了完善的 API 接口,用户无需关心底层寄存器操作细节。

Raw API

Raw API 提供对引擎的完整控制,支持软件密钥和 OTP 密钥:

  • 密钥生成 API:生成 ECC 或 RSA 密钥对

  • 签名 API:使用私钥对数据进行数字签名

  • 验签 API:使用公钥验证签名有效性

  • 密钥交换 API:执行 ECDH 密钥交换

  • OTP 密钥配置 API:配置 OTP 密钥的访问权限

MbedTLS API

为提高兼容性,Realtek 已将硬件加速引擎集成到 MbedTLS API 中。用户可以使用标准的 MbedTLS ECDSA/ECDH API,底层自动调用硬件加速。MbedTLS API 仅支持软件密钥,不支持 OTP 密钥。由于硬件限制,已关闭 MbedTLS 的 SECP521R1 曲线支持。

支持的算法与曲线

各芯片支持的算法曲线如下,ROM 中已预置常用曲线参数,无需用户额外提供:

RTL8721Dx:

不支持。

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.

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.

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))
RTL8721F:

Not supported.

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.

参数:
  • grp -- Pointer to the pke_ecp_group structure.

  • 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).

返回:

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.

参数:
  • 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.

参数:
  • grp -- Pointer to the pke_ecp_group structure.

  • 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 RTK_SUCCESS if the signature is valid, or an error code on failure.

int pke_ecdsa_share_hw_key(int8_t key_id, int8_t is_share)

Configure the sharing attribute of an OTP hardware key (secure-only or shared with non-secure world).

参数:
  • 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.

返回值:
  • 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.

参数:
  • grp -- Pointer to the pke_ecp_group structure.

  • 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 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.

参数:
返回值:
  • 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).

参数:
  • 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 0 on successful key pair generation, or an error code on failure.

备注

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.

参数:
  • 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 0 if the signature is valid and matches the provided message and public key, or an error code if the verification fails.

备注

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.

参数:
  • 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 0 on successful signature generation, or an error code on failure.

备注

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.

参数:
  • grp -- Pointer to the pke_ecp_group structure.

  • 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 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.

参数:
  • grp -- Pointer to the pke_ecp_group structure.

  • 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 0 on successful verification, or an error code on failure.

void pke_engine_init(void)

Initialize PKE engine.

  1. Enable clock and release reset

  2. Initialize engine memory (MMEM / TMEM) to zero.

  3. Set PKE HW key to secure only

RTL8721F:

Not supported.