Skip to content

Commit 68aae28

Browse files
authored
Merge pull request #706 from libtom/new-rsa-api
New RSA API
2 parents 33d8f84 + fa26d13 commit 68aae28

36 files changed

+2096
-820
lines changed

demos/timing.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -731,11 +731,21 @@ static void time_rsa(void)
731731
unsigned char buf[2][2048] = { 0 };
732732
unsigned long x, y, z, zzz;
733733
int err, zz, stat;
734+
ltc_rsa_op_parameters rsa_params = {
735+
.u.crypt.lparam = (const unsigned char *)"testprog",
736+
.u.crypt.lparamlen = 8,
737+
.prng = &yarrow_prng,
738+
.wprng = find_prng("yarrow"),
739+
.params.hash_idx = find_hash("sha1"),
740+
.params.mgf1_hash_idx = find_hash("sha1"),
741+
.params.saltlen = 8,
742+
};
734743

735744
if (ltc_mp.name == NULL) return;
736745

737746
for (x = 2048; x <= 8192; x <<= 1) {
738747
t2 = 0;
748+
rsa_params.padding = LTC_PKCS_1_OAEP;
739749
for (y = 0; y < 4; y++) {
740750
t_start();
741751
t1 = t_read();
@@ -763,9 +773,7 @@ static void time_rsa(void)
763773
t_start();
764774
t1 = t_read();
765775
z = sizeof(buf[1]);
766-
if ((err = rsa_encrypt_key(buf[0], 32, buf[1], &z, (const unsigned char *)"testprog", 8, &yarrow_prng,
767-
find_prng("yarrow"), find_hash("sha1"),
768-
&key)) != CRYPT_OK) {
776+
if ((err = rsa_encrypt_key_v2(buf[0], 32, buf[1], &z, &rsa_params, &key)) != CRYPT_OK) {
769777
fprintf(stderr, "\n\nrsa_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
770778
exit(EXIT_FAILURE);
771779
}
@@ -784,8 +792,7 @@ static void time_rsa(void)
784792
t_start();
785793
t1 = t_read();
786794
zzz = sizeof(buf[0]);
787-
if ((err = rsa_decrypt_key(buf[1], z, buf[0], &zzz, (const unsigned char *)"testprog", 8, find_hash("sha1"),
788-
&zz, &key)) != CRYPT_OK) {
795+
if ((err = rsa_decrypt_key_v2(buf[1], z, buf[0], &zzz, &rsa_params, &zz, &key)) != CRYPT_OK) {
789796
fprintf(stderr, "\n\nrsa_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
790797
exit(EXIT_FAILURE);
791798
}
@@ -800,12 +807,12 @@ static void time_rsa(void)
800807
fprintf(stderr, "RSA-%lu decrypt_key took %15"PRI64"u cycles\n", x, t2);
801808

802809
t2 = 0;
810+
rsa_params.padding = LTC_PKCS_1_PSS;
803811
for (y = 0; y < 256; y++) {
804812
t_start();
805813
t1 = t_read();
806814
z = sizeof(buf[1]);
807-
if ((err = rsa_sign_hash(buf[0], 20, buf[1], &z, &yarrow_prng,
808-
find_prng("yarrow"), find_hash("sha1"), 8, &key)) != CRYPT_OK) {
815+
if ((err = rsa_sign_hash_v2(buf[0], 20, buf[1], &z, &rsa_params, &key)) != CRYPT_OK) {
809816
fprintf(stderr, "\n\nrsa_sign_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
810817
exit(EXIT_FAILURE);
811818
}
@@ -823,7 +830,7 @@ static void time_rsa(void)
823830
for (y = 0; y < 2048; y++) {
824831
t_start();
825832
t1 = t_read();
826-
if ((err = rsa_verify_hash(buf[1], z, buf[0], 20, find_hash("sha1"), 8, &stat, &key)) != CRYPT_OK) {
833+
if ((err = rsa_verify_hash_v2(buf[1], z, buf[0], 20, &rsa_params, &stat, &key)) != CRYPT_OK) {
827834
fprintf(stderr, "\n\nrsa_verify_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
828835
exit(EXIT_FAILURE);
829836
}

doc/crypt.tex

Lines changed: 457 additions & 231 deletions
Large diffs are not rendered by default.

src/headers/tomcrypt_custom.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,10 @@
613613
/* Maximum recursion limit when processing nested ASN.1 types. */
614614
#define LTC_DER_MAX_RECURSION 30
615615
#endif
616+
#ifndef LTC_DER_OID_DEFAULT_NODES
617+
/* Default number of nodes when decoding an OID. */
618+
#define LTC_DER_OID_DEFAULT_NODES 12
619+
#endif
616620
#endif
617621

618622
#if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(LTC_SSH)

src/headers/tomcrypt_pk.h

Lines changed: 116 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ enum ltc_pka_id {
4040
LTC_PKA_X25519,
4141
LTC_PKA_ED25519,
4242
LTC_PKA_DH,
43+
LTC_PKA_RSA_PSS,
4344
LTC_PKA_NUM
4445
};
4546

@@ -62,7 +63,16 @@ int rand_prime(void *N, long len, prng_state *prng, int wprng);
6263
/* ---- RSA ---- */
6364
#ifdef LTC_MRSA
6465

65-
/** RSA PKCS style key */
66+
typedef struct ltc_rsa_parameters {
67+
/** saltLength for PSS */
68+
unsigned long saltlen;
69+
/** Hash algorithm index for OAEP/PSS, -1 if unset */
70+
int hash_idx;
71+
/** MGF1 hash algorithm index, -1 if unset */
72+
int mgf1_hash_idx;
73+
} ltc_rsa_parameters;
74+
75+
/** RSA key */
6676
typedef struct Rsa_key {
6777
/** Type of key, PK_PRIVATE or PK_PUBLIC */
6878
int type;
@@ -82,6 +92,10 @@ typedef struct Rsa_key {
8292
void *dP;
8393
/** The d mod (q - 1) CRT param */
8494
void *dQ;
95+
/** Key is constrained to PSS/OAEP operations */
96+
int pss_oaep;
97+
/** PSS/OAEP parameters of the RSA key */
98+
ltc_rsa_parameters params;
8599
} rsa_key;
86100

87101
int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key);
@@ -95,50 +109,131 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen,
95109

96110
void rsa_free(rsa_key *key);
97111

98-
/* These use PKCS #1 v2.0 padding */
99-
#define rsa_encrypt_key(in, inlen, out, outlen, lparam, lparamlen, prng, prng_idx, hash_idx, key) \
100-
rsa_encrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, prng, prng_idx, hash_idx, -1, LTC_PKCS_1_OAEP, key)
101-
102-
#define rsa_decrypt_key(in, inlen, out, outlen, lparam, lparamlen, hash_idx, stat, key) \
103-
rsa_decrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, hash_idx, -1, LTC_PKCS_1_OAEP, stat, key)
104-
105-
#define rsa_sign_hash(in, inlen, out, outlen, prng, prng_idx, hash_idx, saltlen, key) \
106-
rsa_sign_hash_ex(in, inlen, out, outlen, LTC_PKCS_1_PSS, prng, prng_idx, hash_idx, saltlen, key)
107-
108-
#define rsa_verify_hash(sig, siglen, hash, hashlen, hash_idx, saltlen, stat, key) \
109-
rsa_verify_hash_ex(sig, siglen, hash, hashlen, LTC_PKCS_1_PSS, hash_idx, saltlen, stat, key)
110-
111-
#define rsa_sign_saltlen_get_max(hash_idx, key) \
112-
rsa_sign_saltlen_get_max_ex(LTC_PKCS_1_PSS, hash_idx, key)
112+
typedef struct ltc_rsa_op_parameters {
113+
ltc_rsa_parameters params;
114+
/* The padding type */
115+
int padding;
116+
/* The PRNG to use.
117+
* Only required for signing and encryption. */
118+
int wprng;
119+
prng_state *prng;
120+
/* Operation-specific parameters */
121+
union {
122+
struct {
123+
const unsigned char *lparam;
124+
unsigned long lparamlen;
125+
} crypt;
126+
/* let's make space for potential future extensions */
127+
ulong64 dummy[8];
128+
} u;
129+
} ltc_rsa_op_parameters;
130+
131+
int rsa_encrypt_key_v2(const unsigned char *in, unsigned long inlen,
132+
unsigned char *out, unsigned long *outlen,
133+
ltc_rsa_op_parameters *params,
134+
const rsa_key *key);
135+
136+
int rsa_decrypt_key_v2(const unsigned char *in, unsigned long inlen,
137+
unsigned char *out, unsigned long *outlen,
138+
ltc_rsa_op_parameters *params,
139+
int *stat,
140+
const rsa_key *key);
141+
142+
int rsa_sign_hash_v2(const unsigned char *hash, unsigned long hashlen,
143+
unsigned char *sig, unsigned long *siglen,
144+
ltc_rsa_op_parameters *params,
145+
const rsa_key *key);
146+
147+
int rsa_verify_hash_v2(const unsigned char *sig, unsigned long siglen,
148+
const unsigned char *hash, unsigned long hashlen,
149+
ltc_rsa_op_parameters *params,
150+
int *stat,
151+
const rsa_key *key);
113152

153+
/* These use PKCS #1 v2.0 padding */
154+
#define ltc_rsa_encrypt_key(in, inlen, out, outlen, lp, lplen, prng_, prng_idx, hash_idx_, key) \
155+
rsa_encrypt_key_v2(in, inlen, out, outlen, \
156+
&(ltc_rsa_op_parameters){ \
157+
.u.crypt.lparam = lp, \
158+
.u.crypt.lparamlen = lplen,\
159+
.prng = prng_, \
160+
.wprng = prng_idx, \
161+
.params.mgf1_hash_idx = hash_idx_, \
162+
.params.hash_idx = hash_idx_, \
163+
.padding = LTC_PKCS_1_OAEP, \
164+
}, key)
165+
166+
#define ltc_rsa_decrypt_key(in, inlen, out, outlen, lp, lplen, hash_idx_, stat, key) \
167+
rsa_decrypt_key_v2(in, inlen, out, outlen, \
168+
&(ltc_rsa_op_parameters){ \
169+
.u.crypt.lparam = lp, \
170+
.u.crypt.lparamlen = lplen,\
171+
.params.mgf1_hash_idx = hash_idx_, \
172+
.params.hash_idx = hash_idx_, \
173+
.padding = LTC_PKCS_1_OAEP, \
174+
}, stat, key)
175+
176+
#define ltc_rsa_sign_hash(hash, hashlen, sig, siglen, prng_, prng_idx, hash_idx_, saltlen_, key) \
177+
rsa_sign_hash_v2(hash, hashlen, sig, siglen, \
178+
&(ltc_rsa_op_parameters){ \
179+
.prng = prng_, \
180+
.wprng = prng_idx, \
181+
.params.mgf1_hash_idx = hash_idx_, \
182+
.params.hash_idx = hash_idx_, \
183+
.params.saltlen = saltlen_, \
184+
.padding = LTC_PKCS_1_PSS, \
185+
}, key)
186+
187+
#define ltc_rsa_verify_hash(sig, siglen, hash, hashlen, hash_idx_, saltlen_, stat, key) \
188+
rsa_verify_hash_v2(sig, siglen, hash, hashlen, \
189+
&(ltc_rsa_op_parameters){ \
190+
.params.mgf1_hash_idx = hash_idx_, \
191+
.params.hash_idx = hash_idx_, \
192+
.params.saltlen = saltlen_, \
193+
.padding = LTC_PKCS_1_PSS, \
194+
}, stat, key)
195+
196+
/* If you used those in v1, they're still working */
197+
#define rsa_encrypt_key ltc_rsa_encrypt_key
198+
#define rsa_decrypt_key ltc_rsa_decrypt_key
199+
#define rsa_sign_hash ltc_rsa_sign_hash
200+
#define rsa_verify_hash ltc_rsa_verify_hash
201+
202+
#ifndef LTC_NO_DEPRECATED_APIS
114203
/* These can be switched between PKCS #1 v2.x and PKCS #1 v1.5 paddings */
204+
LTC_DEPRECATED(rsa_encrypt_key_v2)
115205
int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen,
116206
unsigned char *out, unsigned long *outlen,
117207
const unsigned char *lparam, unsigned long lparamlen,
118208
prng_state *prng, int prng_idx,
119-
int mgf_hash, int lparam_hash,
120-
int padding,
209+
int hash_idx, int padding,
121210
const rsa_key *key);
122211

212+
LTC_DEPRECATED(rsa_decrypt_key_v2)
123213
int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen,
124214
unsigned char *out, unsigned long *outlen,
125215
const unsigned char *lparam, unsigned long lparamlen,
126-
int mgf_hash, int lparam_hash,
127-
int padding,
216+
int hash_idx, int padding,
128217
int *stat, const rsa_key *key);
129218

219+
LTC_DEPRECATED(rsa_sign_hash_v2)
130220
int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen,
131221
unsigned char *out, unsigned long *outlen,
132222
int padding,
133-
prng_state *prng, int prng_idx,
223+
prng_state *prng, int prng_idx,
134224
int hash_idx, unsigned long saltlen,
135225
const rsa_key *key);
136226

227+
LTC_DEPRECATED(rsa_verify_hash_v2)
137228
int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
138229
const unsigned char *hash, unsigned long hashlen,
139230
int padding,
140231
int hash_idx, unsigned long saltlen,
141232
int *stat, const rsa_key *key);
233+
#endif /* LTC_NO_DEPRECATED_APIS */
234+
235+
#define rsa_sign_saltlen_get_max(hash_idx, key) \
236+
rsa_sign_saltlen_get_max_ex(LTC_PKCS_1_PSS, hash_idx, key)
142237

143238
int rsa_sign_saltlen_get_max_ex(int padding, int hash_idx, const rsa_key *key);
144239

src/headers/tomcrypt_pkcs.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,19 @@ enum ltc_pkcs_1_paddings
2020
LTC_PKCS_1_V1_5_NA1 = 4 /* PKCS #1 v1.5 padding - No ASN.1 (\sa ltc_pkcs_1_v1_5_blocks) */
2121
};
2222

23+
#ifndef LTC_NO_DEPRECATED_APIS
24+
LTC_DEPRECATED(nothing. API will be internal)
2325
int pkcs_1_mgf1( int hash_idx,
2426
const unsigned char *seed, unsigned long seedlen,
2527
unsigned char *mask, unsigned long masklen);
2628

29+
LTC_DEPRECATED(nothing. API will be removed)
2730
int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out);
31+
LTC_DEPRECATED(nothing. API will be removed)
2832
int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen);
2933

3034
/* *** v1.5 padding */
35+
LTC_DEPRECATED(nothing. API will be internal)
3136
int pkcs_1_v1_5_encode(const unsigned char *msg,
3237
unsigned long msglen,
3338
int block_type,
@@ -37,6 +42,7 @@ int pkcs_1_v1_5_encode(const unsigned char *msg,
3742
unsigned char *out,
3843
unsigned long *outlen);
3944

45+
LTC_DEPRECATED(nothing. API will be internal)
4046
int pkcs_1_v1_5_decode(const unsigned char *msg,
4147
unsigned long msglen,
4248
int block_type,
@@ -46,30 +52,33 @@ int pkcs_1_v1_5_decode(const unsigned char *msg,
4652
int *is_valid);
4753

4854
/* *** v2.1 padding */
55+
LTC_DEPRECATED(nothing. API will be internal)
4956
int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
5057
const unsigned char *lparam, unsigned long lparamlen,
5158
unsigned long modulus_bitlen, prng_state *prng,
52-
int prng_idx,
53-
int mgf_hash, int lparam_hash,
59+
int prng_idx, int hash_idx,
5460
unsigned char *out, unsigned long *outlen);
5561

62+
LTC_DEPRECATED(nothing. API will be internal)
5663
int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
5764
const unsigned char *lparam, unsigned long lparamlen,
58-
unsigned long modulus_bitlen,
59-
int mgf_hash, int lparam_hash,
65+
unsigned long modulus_bitlen, int hash_idx,
6066
unsigned char *out, unsigned long *outlen,
6167
int *res);
6268

69+
LTC_DEPRECATED(nothing. API will be internal)
6370
int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
6471
unsigned long saltlen, prng_state *prng,
6572
int prng_idx, int hash_idx,
6673
unsigned long modulus_bitlen,
6774
unsigned char *out, unsigned long *outlen);
6875

76+
LTC_DEPRECATED(nothing. API will be internal)
6977
int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
7078
const unsigned char *sig, unsigned long siglen,
7179
unsigned long saltlen, int hash_idx,
7280
unsigned long modulus_bitlen, int *res);
81+
#endif /* LTC_NO_DEPRECATED_APIS */
7382

7483
#endif /* LTC_PKCS_1 */
7584

0 commit comments

Comments
 (0)