Skip to content

Commit e6605ca

Browse files
committed
Refactor SubjectPublicKeyInfo import
Slightly minimize both space and time when importing a SubjectPublicKeyInfo. Time for ECC keys stays the same. Running the entire set of pem files through `x509_verify` via [0] resp. the timing app via [1] resulted in the following data: Before this patch: [0] ``` ==1031519== HEAP SUMMARY: ==1031519== in use at exit: 0 bytes in 0 blocks ==1031519== total heap usage: 424,057 allocs, 424,057 frees, 73,527,730 bytes allocated ``` [1] ``` x509 cert-rsa-pss.pem : 50021 cycles x509 LTC_CA.pem : 10335 cycles x509 LTC_S0.pem : 47284 cycles x509 LTC_SS0.pem : 36687 cycles x509 secp384r1.pem : 1985416 cycles x509 secp521r1.pem : 3287773 cycles x509 LTC_SSS0.pem : 25086 cycles x509 secp224r1.pem : 775807 cycles ``` After this patch: [0] ``` ==1043548== HEAP SUMMARY: ==1043548== in use at exit: 0 bytes in 0 blocks ==1043548== total heap usage: 337,244 allocs, 337,244 frees, 65,047,463 bytes allocated ``` [1] ``` x509 cert-rsa-pss.pem : 32568 cycles x509 LTC_CA.pem : 5478 cycles x509 LTC_S0.pem : 36093 cycles x509 LTC_SS0.pem : 23351 cycles x509 secp384r1.pem : 1984030 cycles x509 secp521r1.pem : 3303396 cycles x509 LTC_SSS0.pem : 13220 cycles x509 secp224r1.pem : 781534 cycles ``` [0] find tests/x509 -name '*.pem' -exec valgrind --leak-check=full --show-leak-kinds=all './x509_verify' {} \+ [1] ./timing x509 Signed-off-by: Steffen Jaeckel <[email protected]>
1 parent aa39e39 commit e6605ca

File tree

6 files changed

+195
-81
lines changed

6 files changed

+195
-81
lines changed

src/headers/tomcrypt_private.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,8 @@ int rsa_make_key_bn_e(prng_state *prng, int wprng, int size, void *e,
454454
rsa_key *key); /* used by op-tee */
455455
int rsa_import_pkcs1(const unsigned char *in, unsigned long inlen, rsa_key *key);
456456
int rsa_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, rsa_key *key);
457+
int rsa_import_spki(const unsigned char *in, unsigned long inlen, rsa_key *key);
458+
int rsa_decode_parameters(const ltc_asn1_list *parameters, ltc_rsa_parameters *rsa_params);
457459
#endif /* LTC_MRSA */
458460

459461
/* ---- DH Routines ---- */
@@ -561,8 +563,8 @@ int dsa_int_validate(const dsa_key *key, int *stat);
561563
int dsa_int_validate_xy(const dsa_key *key, int *stat);
562564
int dsa_int_validate_pqg(const dsa_key *key, int *stat);
563565
int dsa_int_validate_primes(const dsa_key *key, int *stat);
564-
int dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key);
565566
int dsa_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, dsa_key *key);
567+
int dsa_import_spki(const unsigned char *in, unsigned long inlen, dsa_key *key);
566568
#endif /* LTC_MDSA */
567569

568570

src/pk/asn1/x509/x509_import.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,11 @@ static int s_x509_get_sig_alg(const ltc_asn1_list *seq, ltc_x509_signature_algor
272272
if ((err = x509_get_sig_alg(&fake_sig_parent, sig_alg)) != CRYPT_OK) {
273273
return err;
274274
}
275+
if (sig_alg->pka == LTC_PKA_RSA_PSS && seq->child && seq->child->next) {
276+
if ((err = rsa_decode_parameters(seq->child->next, &sig_alg->u.rsa_params)) != CRYPT_OK) {
277+
return err;
278+
}
279+
}
275280
sig_alg->asn1 = seq;
276281
return err;
277282
}

src/pk/asn1/x509/x509_import_spki.c

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,48 @@
99

1010
#ifdef LTC_DER
1111

12-
typedef int (*import_fn)(const unsigned char *, unsigned long, void*);
12+
typedef int (*import_fn)(const unsigned char *, unsigned long, void *);
1313

14-
static const import_fn s_import_x509_fns[LTC_PKA_NUM] = {
14+
#ifdef LTC_CURVE25519
15+
static int s_x25519_import_pub(const unsigned char *in, unsigned long inlen, void *key)
16+
{
17+
return x25519_import_raw(in, inlen, PK_PUBLIC, key);
18+
}
19+
static int s_x25519_import_spki(const unsigned char *in, unsigned long inlen, void *key)
20+
{
21+
return x509_process_public_key_from_spki(in, inlen,
22+
LTC_OID_X25519,
23+
LTC_ASN1_EOL, NULL, NULL,
24+
s_x25519_import_pub, key);
25+
}
26+
27+
static int s_ed25519_import_pub(const unsigned char *in, unsigned long inlen, void *key)
28+
{
29+
return ed25519_import_raw(in, inlen, PK_PUBLIC, key);
30+
}
31+
static int s_ed25519_import_spki(const unsigned char *in, unsigned long inlen, void *key)
32+
{
33+
return x509_process_public_key_from_spki(in, inlen,
34+
LTC_OID_ED25519,
35+
LTC_ASN1_EOL, NULL, NULL,
36+
s_ed25519_import_pub, key);
37+
}
38+
#endif
39+
40+
static const import_fn s_import_spki_fns[LTC_PKA_NUM] = {
1541
#ifdef LTC_MRSA
16-
[LTC_PKA_RSA] = (import_fn)rsa_import_x509,
17-
[LTC_PKA_RSA_PSS] = (import_fn)rsa_import_x509,
42+
[LTC_PKA_RSA] = (import_fn)rsa_import_spki,
43+
[LTC_PKA_RSA_PSS] = (import_fn)rsa_import_spki,
1844
#endif
1945
#ifdef LTC_MDSA
20-
[LTC_PKA_DSA] = (import_fn)dsa_import,
46+
[LTC_PKA_DSA] = (import_fn)dsa_import_spki,
2147
#endif
2248
#ifdef LTC_MECC
23-
[LTC_PKA_EC] = (import_fn)ecc_import_x509,
49+
[LTC_PKA_EC] = (import_fn)ecc_import_subject_public_key_info,
2450
#endif
2551
#ifdef LTC_CURVE25519
26-
[LTC_PKA_X25519] = (import_fn)x25519_import_x509,
27-
[LTC_PKA_ED25519] = (import_fn)ed25519_import_x509,
52+
[LTC_PKA_X25519] = (import_fn)s_x25519_import_spki,
53+
[LTC_PKA_ED25519] = (import_fn)s_ed25519_import_spki,
2854
#endif
2955
};
3056

@@ -41,12 +67,12 @@ int x509_import_spki(const unsigned char *asn1_cert, unsigned long asn1_len, ltc
4167
goto err_out;
4268
}
4369
if (pka < 0
44-
|| pka > LTC_ARRAY_SIZE(s_import_x509_fns)
45-
|| s_import_x509_fns[pka] == NULL) {
70+
|| pka > LTC_ARRAY_SIZE(s_import_spki_fns)
71+
|| s_import_spki_fns[pka] == NULL) {
4672
err = CRYPT_PK_INVALID_TYPE;
4773
goto err_out;
4874
}
49-
if ((err = s_import_x509_fns[pka](asn1_cert, asn1_len, &k->u)) == CRYPT_OK) {
75+
if ((err = s_import_spki_fns[pka](spki->data, spki->size, &k->u)) == CRYPT_OK) {
5076
k->id = pka;
5177
}
5278
err_out:

src/pk/dsa/dsa_import.c

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
#ifdef LTC_MDSA
1111

12-
int dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key)
12+
static int s_dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key)
1313
{
1414
int err;
1515
unsigned long zero = 0;
@@ -33,14 +33,32 @@ static int s_dsa_import_y(const unsigned char *in, unsigned long inlen, dsa_key
3333
return der_decode_integer(in, inlen, key->y);
3434
}
3535

36-
LTC_INLINE static int s_dsa_set_params(dsa_key *key, ltc_asn1_list *params)
36+
static LTC_INLINE int s_dsa_set_params(dsa_key *key, ltc_asn1_list *params)
3737
{
3838
LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL);
3939
LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL);
4040
LTC_SET_ASN1(params, 2, LTC_ASN1_INTEGER, key->g, 1UL);
4141
return 3;
4242
}
4343

44+
static LTC_INLINE int s_dsa_validate(dsa_key *key)
45+
{
46+
int err, stat;
47+
key->qord = ltc_mp_unsigned_bin_size(key->q);
48+
49+
/* quick p, q, g validation, without primality testing
50+
* + x, y validation */
51+
if ((err = dsa_int_validate(key, &stat)) != CRYPT_OK) {
52+
return err;
53+
}
54+
55+
if (stat == 0) {
56+
return CRYPT_INVALID_PACKET;
57+
}
58+
59+
return CRYPT_OK;
60+
}
61+
4462
static int s_dsa_import_spki(const unsigned char *in, unsigned long inlen, dsa_key *key)
4563
{
4664
int err;
@@ -72,6 +90,28 @@ static int s_dsa_import_spki(const unsigned char *in, unsigned long inlen, dsa_k
7290
return err;
7391
}
7492

93+
int dsa_import_spki(const unsigned char *in, unsigned long inlen, dsa_key *key)
94+
{
95+
int err;
96+
97+
LTC_ARGCHK(in != NULL);
98+
99+
/* init key */
100+
if ((err = dsa_int_init(key)) != CRYPT_OK) return err;
101+
102+
if ((err = s_dsa_import_spki(in, inlen, key)) != CRYPT_OK) {
103+
goto LBL_ERR;
104+
}
105+
if ((err = s_dsa_validate(key)) != CRYPT_OK) {
106+
goto LBL_ERR;
107+
}
108+
109+
return CRYPT_OK;
110+
LBL_ERR:
111+
dsa_free(key);
112+
return err;
113+
}
114+
75115
static int s_dsa_import_x509(const unsigned char *in, unsigned long inlen, dsa_key *key)
76116
{
77117
int err;
@@ -100,7 +140,7 @@ static int s_dsa_import_x509(const unsigned char *in, unsigned long inlen, dsa_k
100140
*/
101141
int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
102142
{
103-
int err, stat;
143+
int err;
104144
unsigned char flags[1];
105145

106146
LTC_ARGCHK(in != NULL);
@@ -148,26 +188,18 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
148188
}
149189
}
150190

151-
if (dsa_import_pkcs1(in, inlen, key) == CRYPT_OK) {
191+
if (s_dsa_import_pkcs1(in, inlen, key) == CRYPT_OK) {
152192
goto LBL_OK;
153193
}
154-
if ((err = s_dsa_import_spki(in, inlen, key)) == CRYPT_OK) {
194+
if (s_dsa_import_spki(in, inlen, key) == CRYPT_OK) {
155195
goto LBL_OK;
156196
}
157197
if ((err = s_dsa_import_x509(in, inlen, key)) != CRYPT_OK) {
158198
goto LBL_ERR;
159199
}
160200

161201
LBL_OK:
162-
key->qord = ltc_mp_unsigned_bin_size(key->q);
163-
164-
/* quick p, q, g validation, without primality testing
165-
* + x, y validation */
166-
if ((err = dsa_int_validate(key, &stat)) != CRYPT_OK) {
167-
goto LBL_ERR;
168-
}
169-
if (stat == 0) {
170-
err = CRYPT_INVALID_PACKET;
202+
if ((err = s_dsa_validate(key)) != CRYPT_OK) {
171203
goto LBL_ERR;
172204
}
173205

src/pk/rsa/rsa_import.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,23 +99,18 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
9999
LTC_ARGCHK(key != NULL);
100100
LTC_ARGCHK(ltc_mp.name != NULL);
101101

102-
if ((err = rsa_import_x509(in, inlen, key)) == CRYPT_OK) { /* SubjectPublicKeyInfo format */
102+
/* SubjectPublicKeyInfo or X.509 certificate format */
103+
if (rsa_import_x509(in, inlen, key) == CRYPT_OK) {
103104
return CRYPT_OK;
104105
}
105106

106107
/* init key */
107108
if ((err = rsa_init(key)) != CRYPT_OK) {
108109
return err;
109110
}
110-
111-
if ((err = x509_process_public_key_from_spki(in, inlen,
112-
LTC_OID_RSA,
113-
LTC_ASN1_NULL, NULL, NULL,
114-
(public_key_decode_cb)s_rsa_decode, key)) != CRYPT_OK) {
115-
/* not SSL public key, try to match against PKCS #1 standards */
116-
if ((err = rsa_import_pkcs1(in, inlen, key)) != CRYPT_OK) {
117-
rsa_free(key);
118-
}
111+
/* Try to match against PKCS #1 standards */
112+
if ((err = rsa_import_pkcs1(in, inlen, key)) != CRYPT_OK) {
113+
rsa_free(key);
119114
}
120115

121116
return err;

0 commit comments

Comments
 (0)