Skip to content

Commit 4eadfbe

Browse files
authored
Implement faster RSA key check
1 parent d688a80 commit 4eadfbe

File tree

6 files changed

+317
-12
lines changed

6 files changed

+317
-12
lines changed

src/native/libs/System.Security.Cryptography.Native/apibridge.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,14 @@ void local_RSA_get0_crt_params(const RSA* rsa, const BIGNUM** dmp1, const BIGNUM
442442
}
443443
}
444444

445+
int local_RSA_get_multi_prime_extra_count(const RSA* rsa)
446+
{
447+
(void)rsa;
448+
// OpenSSL before 1.1 does not support multi-prime RSA, so it implicitly
449+
// has zero extra primes.
450+
return 0;
451+
}
452+
445453
int32_t local_RSA_set0_key(RSA* rsa, BIGNUM* n, BIGNUM* e, BIGNUM* d)
446454
{
447455
if (rsa == NULL)
@@ -909,4 +917,19 @@ int local_BN_is_zero(const BIGNUM* a)
909917
return a->top == 0;
910918
}
911919

920+
int local_BN_is_one(const BIGNUM* a)
921+
{
922+
return BN_abs_is_word(a, 1) && !a->neg;
923+
}
924+
925+
int local_BN_abs_is_word(const BIGNUM *a, const BN_ULONG w)
926+
{
927+
return ((a->top == 1) && (a->d[0] == w)) || ((w == 0) && (a->top == 0));
928+
}
929+
930+
int local_BN_is_odd(const BIGNUM* a)
931+
{
932+
return (a->top > 0) && (a->d[0] & 1);
933+
}
934+
912935
#endif

src/native/libs/System.Security.Cryptography.Native/apibridge.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
#include "pal_types.h"
88

99
int local_ASN1_TIME_to_tm(const ASN1_TIME* s, struct tm* tm);
10+
int local_BN_abs_is_word(const BIGNUM *a, const BN_ULONG w);
1011
int local_BN_is_zero(const BIGNUM* a);
12+
int local_BN_is_odd(const BIGNUM* a);
13+
int local_BN_is_one(const BIGNUM* a);
1114
int local_BIO_up_ref(BIO *a);
1215
const BIGNUM* local_DSA_get0_key(const DSA* dsa, const BIGNUM** pubKey, const BIGNUM** privKey);
1316
void local_DSA_get0_pqg(const DSA* dsa, const BIGNUM** p, const BIGNUM** q, const BIGNUM** g);
@@ -27,6 +30,7 @@ long local_OpenSSL_version_num(void);
2730
void local_RSA_get0_crt_params(const RSA* rsa, const BIGNUM** dmp1, const BIGNUM** dmq1, const BIGNUM** iqmp);
2831
void local_RSA_get0_factors(const RSA* rsa, const BIGNUM** p, const BIGNUM** q);
2932
void local_RSA_get0_key(const RSA* rsa, const BIGNUM** n, const BIGNUM** e, const BIGNUM** d);
33+
int local_RSA_get_multi_prime_extra_count(const RSA* r);
3034
int32_t local_RSA_meth_get_flags(const RSA_METHOD* meth);
3135
int32_t local_RSA_set0_crt_params(RSA* rsa, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* iqmp);
3236
int32_t local_RSA_set0_factors(RSA* rsa, BIGNUM* p, BIGNUM* q);

src/native/libs/System.Security.Cryptography.Native/openssl_1_0_structs.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,11 @@ struct bio_st
185185
int references;
186186
};
187187

188-
struct bignum_st {
189-
const void* _ignored1;
188+
struct bignum_st
189+
{
190+
BN_ULONG *d;
190191
int top;
191-
int _ignored2;
192-
int _ignored3;
193-
int _ignored4;
192+
int dmax;
193+
int neg;
194+
int flags;
194195
};

src/native/libs/System.Security.Cryptography.Native/opensslshim.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@
5757
#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0_RTM
5858

5959
// Remove problematic #defines
60+
#undef BN_abs_is_word
61+
#undef BN_is_odd
62+
#undef BN_is_one
6063
#undef BN_is_zero
6164
#undef SSL_get_state
6265
#undef SSL_is_init_finished
@@ -210,15 +213,28 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t len);
210213
FALLBACK_FUNCTION(BIO_up_ref) \
211214
REQUIRED_FUNCTION(BIO_s_mem) \
212215
REQUIRED_FUNCTION(BIO_write) \
216+
FALLBACK_FUNCTION(BN_abs_is_word) \
213217
REQUIRED_FUNCTION(BN_bin2bn) \
214218
REQUIRED_FUNCTION(BN_bn2bin) \
215219
REQUIRED_FUNCTION(BN_clear_free) \
220+
REQUIRED_FUNCTION(BN_cmp) \
221+
REQUIRED_FUNCTION(BN_div) \
216222
REQUIRED_FUNCTION(BN_dup) \
217223
REQUIRED_FUNCTION(BN_free) \
224+
REQUIRED_FUNCTION(BN_gcd) \
225+
FALLBACK_FUNCTION(BN_is_odd) \
226+
FALLBACK_FUNCTION(BN_is_one) \
218227
FALLBACK_FUNCTION(BN_is_zero) \
228+
REQUIRED_FUNCTION(BN_mod_inverse) \
229+
REQUIRED_FUNCTION(BN_mod_mul) \
230+
REQUIRED_FUNCTION(BN_mul) \
219231
REQUIRED_FUNCTION(BN_new) \
220232
REQUIRED_FUNCTION(BN_num_bits) \
221233
REQUIRED_FUNCTION(BN_set_word) \
234+
REQUIRED_FUNCTION(BN_sub) \
235+
REQUIRED_FUNCTION(BN_value_one) \
236+
REQUIRED_FUNCTION(BN_CTX_new) \
237+
REQUIRED_FUNCTION(BN_CTX_free) \
222238
LEGACY_FUNCTION(CRYPTO_add_lock) \
223239
REQUIRED_FUNCTION(CRYPTO_free) \
224240
REQUIRED_FUNCTION(CRYPTO_get_ex_new_index) \
@@ -496,6 +512,7 @@ int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t len);
496512
REQUIRED_FUNCTION(RSA_free) \
497513
REQUIRED_FUNCTION(RSA_generate_key_ex) \
498514
REQUIRED_FUNCTION(RSA_get_method) \
515+
FALLBACK_FUNCTION(RSA_get_multi_prime_extra_count) \
499516
FALLBACK_FUNCTION(RSA_get0_crt_params) \
500517
FALLBACK_FUNCTION(RSA_get0_factors) \
501518
FALLBACK_FUNCTION(RSA_get0_key) \
@@ -722,15 +739,28 @@ FOR_ALL_OPENSSL_FUNCTIONS
722739
#define BIO_up_ref BIO_up_ref_ptr
723740
#define BIO_s_mem BIO_s_mem_ptr
724741
#define BIO_write BIO_write_ptr
742+
#define BN_abs_is_word BN_abs_is_word_ptr
725743
#define BN_bin2bn BN_bin2bn_ptr
726744
#define BN_bn2bin BN_bn2bin_ptr
727745
#define BN_clear_free BN_clear_free_ptr
746+
#define BN_cmp BN_cmp_ptr
747+
#define BN_div BN_div_ptr
728748
#define BN_dup BN_dup_ptr
729749
#define BN_free BN_free_ptr
750+
#define BN_gcd BN_gcd_ptr
751+
#define BN_is_odd BN_is_odd_ptr
752+
#define BN_is_one BN_is_one_ptr
730753
#define BN_is_zero BN_is_zero_ptr
754+
#define BN_mod_inverse BN_mod_inverse_ptr
755+
#define BN_mod_mul BN_mod_mul_ptr
756+
#define BN_mul BN_mul_ptr
731757
#define BN_new BN_new_ptr
732758
#define BN_num_bits BN_num_bits_ptr
733759
#define BN_set_word BN_set_word_ptr
760+
#define BN_sub BN_sub_ptr
761+
#define BN_value_one BN_value_one_ptr
762+
#define BN_CTX_free BN_CTX_free_ptr
763+
#define BN_CTX_new BN_CTX_new_ptr
734764
#define CRYPTO_add_lock CRYPTO_add_lock_ptr
735765
#define CRYPTO_free CRYPTO_free_ptr
736766
#define CRYPTO_get_ex_new_index CRYPTO_get_ex_new_index_ptr
@@ -1011,6 +1041,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
10111041
#define RSA_get0_factors RSA_get0_factors_ptr
10121042
#define RSA_get0_key RSA_get0_key_ptr
10131043
#define RSA_get_method RSA_get_method_ptr
1044+
#define RSA_get_multi_prime_extra_count RSA_get_multi_prime_extra_count_ptr
10141045
#define RSA_meth_get_flags RSA_meth_get_flags_ptr
10151046
#define RSA_new RSA_new_ptr
10161047
#define RSA_pkey_ctx_ctrl RSA_pkey_ctx_ctrl_ptr
@@ -1270,6 +1301,9 @@ FOR_ALL_OPENSSL_FUNCTIONS
12701301

12711302
// Alias "future" API to the local_ version.
12721303
#define ASN1_TIME_to_tm local_ASN1_TIME_to_tm
1304+
#define BN_abs_is_word local_BN_abs_is_word
1305+
#define BN_is_odd local_BN_is_odd
1306+
#define BN_is_one local_BN_is_one
12731307
#define BN_is_zero local_BN_is_zero
12741308
#define BIO_up_ref local_BIO_up_ref
12751309
#define DSA_get0_key local_DSA_get0_key
@@ -1287,6 +1321,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
12871321
#define HMAC_CTX_free local_HMAC_CTX_free
12881322
#define HMAC_CTX_new local_HMAC_CTX_new
12891323
#define OpenSSL_version_num local_OpenSSL_version_num
1324+
#define RSA_get_multi_prime_extra_count local_RSA_get_multi_prime_extra_count
12901325
#define RSA_get0_crt_params local_RSA_get0_crt_params
12911326
#define RSA_get0_factors local_RSA_get0_factors
12921327
#define RSA_get0_key local_RSA_get0_key

src/native/libs/System.Security.Cryptography.Native/osslcompat_111.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
#pragma once
77
#include "pal_types.h"
88

9+
#undef BN_abs_is_word
10+
#undef BN_is_odd
11+
#undef BN_is_one
912
#undef BN_is_zero
1013
#undef SSL_CTX_set_options
1114
#undef SSL_set_options
@@ -21,6 +24,9 @@ typedef struct stack_st OPENSSL_STACK;
2124
#define OPENSSL_INIT_LOAD_SSL_STRINGS 0x00200000L
2225

2326
int ASN1_TIME_to_tm(const ASN1_TIME* s, struct tm* tm);
27+
int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w);
28+
int BN_is_odd(const BIGNUM* a);
29+
int BN_is_one(const BIGNUM* a);
2430
int BN_is_zero(const BIGNUM* a);
2531
int BIO_up_ref(BIO* a);
2632
const BIGNUM* DSA_get0_key(const DSA* dsa, const BIGNUM** pubKey, const BIGNUM** privKey);
@@ -52,6 +58,7 @@ const RSA_METHOD* RSA_PKCS1_OpenSSL(void);
5258
void RSA_get0_crt_params(const RSA* rsa, const BIGNUM** dmp1, const BIGNUM** dmq1, const BIGNUM** iqmp);
5359
void RSA_get0_factors(const RSA* rsa, const BIGNUM** p, const BIGNUM** q);
5460
void RSA_get0_key(const RSA* rsa, const BIGNUM** n, const BIGNUM** e, const BIGNUM** d);
61+
int RSA_get_multi_prime_extra_count(const RSA* r);
5562
int32_t RSA_meth_get_flags(const RSA_METHOD* meth);
5663
int32_t RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int32_t optype, int32_t cmd, int32_t p1, void* p2);
5764
int32_t RSA_set0_crt_params(RSA* rsa, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* iqmp);

0 commit comments

Comments
 (0)