文件

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 */