138 行
5.8 KiB
C
138 行
5.8 KiB
C
/* rsa.h —— RSA 公钥/私钥算法 (PKCS#1)
|
|
*
|
|
* 实现:
|
|
* - RSAES-PKCS1-v1_5 加解密 (TLS 1.2 RSA 密钥交换)
|
|
* - RSASSA-PKCS1-v1_5 签名/验签 (TLS 1.2 证书签名)
|
|
* - RSASSA-PSS 签名/验签 (TLS 1.3)
|
|
* - 密钥生成、PKCS#1 DER 导入导出
|
|
*
|
|
* 私钥用 CRT 参数加速解密/签名 (p, q, dP, dQ, qInv)。
|
|
* 大数运算复用 bignum.c (Montgomery 模幂)。
|
|
*
|
|
* 参考:RFC 8017 (PKCS#1 v2.2)。
|
|
*/
|
|
#ifndef PAZE_RSA_H
|
|
#define PAZE_RSA_H
|
|
|
|
#include "paze/paze_types.h"
|
|
#include "paze/bignum.h"
|
|
#include "paze/hash.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* 公钥:n, e */
|
|
typedef struct {
|
|
paze_bn_t n; /* 模数 */
|
|
paze_bn_t e; /* 公钥指数 */
|
|
} paze_rsa_pub_t;
|
|
|
|
/* 私钥:CRT 参数。
|
|
* d = e^(-1) mod phi
|
|
* dP = d mod (p-1), dQ = d mod (q-1), qInv = q^(-1) mod p
|
|
* 解密/签名:m1 = c^dP mod p, m2 = c^dQ mod q, m = m2 + q*(qInv*(m1-m2) mod p) */
|
|
typedef struct {
|
|
paze_bn_t n, e; /* 公钥部分(同 paze_rsa_pub_t) */
|
|
paze_bn_t d; /* 私钥指数 */
|
|
paze_bn_t p, q; /* 素因子 (p > q 约定) */
|
|
paze_bn_t dP, dQ; /* CRT 指数 */
|
|
paze_bn_t qInv; /* CRT 系数 */
|
|
} paze_rsa_priv_t;
|
|
|
|
/* 哈希算法标识 (PKCS#1 DigestInfo 前缀用) */
|
|
typedef enum {
|
|
PAZE_RSA_HASH_SHA1 = 0,
|
|
PAZE_RSA_HASH_SHA224 = 1,
|
|
PAZE_RSA_HASH_SHA256 = 2,
|
|
PAZE_RSA_HASH_SHA384 = 3,
|
|
PAZE_RSA_HASH_SHA512 = 4
|
|
} paze_rsa_hash_t;
|
|
|
|
/* ---- 密钥生成 ----
|
|
* 生成 bits 位的 RSA 密钥对 (n 为 bits 位,e = 65537)。
|
|
* p, q 各为 bits/2 位。返回私钥(含公钥部分)。
|
|
* bits 须 >= 512,建议 2048/3072/4096。 */
|
|
paze_status_t paze_rsa_gen(paze_rsa_priv_t *k, int bits);
|
|
|
|
/* 从私钥提取公钥 */
|
|
paze_status_t paze_rsa_pub_from_priv(paze_rsa_pub_t *pub, const paze_rsa_priv_t *priv);
|
|
|
|
/* ---- I2OSP / OS2IP ---- (内部用,导出供测试)
|
|
* I2OSP: 整数 -> 固定长度大端字节串
|
|
* OS2IP: 大端字节串 -> 整数 */
|
|
paze_status_t paze_rsa_i2osp(uint8_t *out, size_t len, const paze_bn_t *x);
|
|
paze_status_t paze_rsa_os2ip(paze_bn_t *x, const uint8_t *in, size_t len);
|
|
|
|
/* ---- RSAES-PKCS1-v1_5 ----
|
|
* 加密:msg 长度 <= k-11 (k = 字节模数长度)。out 为 k 字节。
|
|
* 用 paze_random 生成随机 padding。 */
|
|
paze_status_t paze_rsa_pkcs1_encrypt(const paze_rsa_pub_t *pub,
|
|
const uint8_t *msg, size_t msglen,
|
|
uint8_t *out, size_t outlen);
|
|
/* 解密:in 为 k 字节,out 写明文,*outlen 给出容量,写回实际长度。
|
|
* 常量时间检查 padding 头(防 Bleichenbacher 选择密文攻击的部分缓解)。 */
|
|
paze_status_t paze_rsa_pkcs1_decrypt(const paze_rsa_priv_t *priv,
|
|
const uint8_t *in, size_t inlen,
|
|
uint8_t *out, size_t *outlen);
|
|
|
|
/* ---- RSASSA-PKCS1-v1_5 ----
|
|
* 签名:对 hash(m) 签名。sig 为 k 字节。hash_alg 指定哈希。
|
|
* mhash 长度须匹配 hash_alg 的摘要长度。 */
|
|
paze_status_t paze_rsa_pkcs1_sign(const paze_rsa_priv_t *priv,
|
|
paze_rsa_hash_t hash_alg,
|
|
const uint8_t *mhash, size_t hlen,
|
|
uint8_t *sig, size_t siglen);
|
|
/* 验签:返回 PAZE_OK=通过, PAZE_ERR_VERIFY=失败。 */
|
|
paze_status_t paze_rsa_pkcs1_verify(const paze_rsa_pub_t *pub,
|
|
paze_rsa_hash_t hash_alg,
|
|
const uint8_t *mhash, size_t hlen,
|
|
const uint8_t *sig, size_t siglen);
|
|
|
|
/* ---- RSASSA-PSS ----
|
|
* PSS 签名/验签,盐长度 = hlen (摘要长度)。
|
|
* MGF1 基于 hash_alg。em_bits = bitlen(n) - 1。 */
|
|
paze_status_t paze_rsa_pss_sign(const paze_rsa_priv_t *priv,
|
|
paze_rsa_hash_t hash_alg,
|
|
const uint8_t *mhash, size_t hlen,
|
|
uint8_t *sig, size_t siglen);
|
|
paze_status_t paze_rsa_pss_verify(const paze_rsa_pub_t *pub,
|
|
paze_rsa_hash_t hash_alg,
|
|
const uint8_t *mhash, size_t hlen,
|
|
const uint8_t *sig, size_t siglen);
|
|
|
|
/* ---- 原始 RSA (教科书式,无 padding) ---- 供测试与内部用 */
|
|
paze_status_t paze_rsa_public_op(paze_bn_t *r, const paze_bn_t *m,
|
|
const paze_rsa_pub_t *pub); /* r = m^e mod n */
|
|
paze_status_t paze_rsa_private_op(paze_bn_t *m, const paze_bn_t *c,
|
|
const paze_rsa_priv_t *priv); /* m = c^d mod n (CRT) */
|
|
|
|
/* ---- PKCS#1 DER 导入导出 ----
|
|
* RSAPublicKey ::= SEQUENCE { n INTEGER, e INTEGER }
|
|
* RSAPrivateKey ::= SEQUENCE { version, n, e, d, p, q, dP, dQ, qInv }
|
|
* 编码到 out,*outlen 给出容量/写回实际长度。返回 PAZE_ERR_SHORT 若容量不足。 */
|
|
paze_status_t paze_rsa_pub_to_der(const paze_rsa_pub_t *pub,
|
|
uint8_t *out, size_t *outlen);
|
|
paze_status_t paze_rsa_priv_to_der(const paze_rsa_priv_t *priv,
|
|
uint8_t *out, size_t *outlen);
|
|
paze_status_t paze_rsa_pub_from_der(paze_rsa_pub_t *pub,
|
|
const uint8_t *der, size_t len);
|
|
paze_status_t paze_rsa_priv_from_der(paze_rsa_priv_t *priv,
|
|
const uint8_t *der, size_t len);
|
|
|
|
/* PEM 包装:从 PEM 文本("RSA PRIVATE KEY" label)中加载私钥 */
|
|
paze_status_t paze_rsa_priv_from_pem(paze_rsa_priv_t *priv, const char *pem_text);
|
|
/* PEM 包装:从 PEM 文本中加载公钥("RSA PUBLIC KEY" label) */
|
|
paze_status_t paze_rsa_pub_from_pem(paze_rsa_pub_t *pub, const char *pem_text);
|
|
|
|
/* 模数字节长度 k = ceil(bitlen(n)/8) */
|
|
size_t paze_rsa_modulus_len(const paze_bn_t *n);
|
|
|
|
/* 哈希摘要长度(字节) */
|
|
size_t paze_rsa_hash_len(paze_rsa_hash_t h);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#endif /* PAZE_RSA_H */
|