Skip to content

Commit 049120a

Browse files
authored
Merge pull request #66 from timlegge/pss_padding
Clarify the padding and fix some missing frees for openssl objects
2 parents bb6cf94 + 06d1275 commit 049120a

File tree

5 files changed

+299
-14
lines changed

5 files changed

+299
-14
lines changed

README

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ SYNOPSIS
1313
$ciphertext = $rsa->encrypt($plaintext);
1414

1515
$rsa_priv = Crypt::OpenSSL::RSA->new_private_key($key_string);
16-
$plaintext = $rsa->encrypt($ciphertext);
16+
$plaintext = $rsa->decrypt($ciphertext);
1717

1818
$rsa = Crypt::OpenSSL::RSA->generate_key(1024); # or
1919
$rsa = Crypt::OpenSSL::RSA->generate_key(1024, $prime);
@@ -28,6 +28,15 @@ SYNOPSIS
2828
$signature = $rsa_priv->sign($plaintext);
2929
print "Signed correctly\n" if ($rsa->verify($plaintext, $signature));
3030

31+
SECURITY
32+
Version 0.35 makes the use of PKCS#1 v1.5 padding a fatal error. It is
33+
very difficult to implement PKCS#1 v1.5 padding securely. If you are
34+
still using RSA in in general, you should be looking at alternative
35+
encryption algorithms. Version 0.36 implements RSA-PSS padding (PKCS#1
36+
v2.1) and makes setting an invalid padding a fatal error. Note,
37+
PKCS1_OAEP can only be used for encryption and PKCS1_PSS can only be
38+
used for signing.
39+
3140
DESCRIPTION
3241
"Crypt::OpenSSL::RSA" provides the ability to RSA encrypt strings which
3342
are somewhat shorter than the block size of a key. It also allows for
@@ -48,6 +57,10 @@ Class Methods
4857
The padding is set to PKCS1_OAEP, but can be changed with the
4958
"use_xxx_padding" methods.
5059

60+
Note, PKCS1_OAEP can only be used for encryption. You must
61+
specifically call use_pkcs1_pss_padding (or use_pkcs1_pss_padding)
62+
prior to signing operations.
63+
5164
new_private_key
5265
Create a new "Crypt::OpenSSL::RSA" object by loading a private key
5366
in from an string containing the Base64/DER encoding of the PKCS1
@@ -140,27 +153,53 @@ Instance Methods
140153
verify
141154
Check the signature on a text.
142155

156+
Padding Methods
157+
Versions prior to 0.35 allowed using pkcs1 padding for both encryption
158+
and signature operations but has been disabled for security reasons.
159+
160+
While use_no_padding can be used for encryption or signature operations
161+
use_pkcs1_pss_padding is used for signature operations and
162+
use_pkcs1_oaep_padding is used for encryption operations.
163+
164+
Version 0.38 sets the appropriate padding for each operation unless
165+
use_no_padding is called before either operation.
166+
143167
use_no_padding
144168
Use raw RSA encryption. This mode should only be used to implement
145169
cryptographically sound padding modes in the application code.
146170
Encrypting user data directly with RSA is insecure.
147171

148172
use_pkcs1_padding
149-
Use PKCS #1 v1.5 padding. This currently is the most widely used
150-
mode of padding.
173+
PKCS #1 v1.5 padding has been disabled as it is nearly impossible to
174+
use this padding method in a secure manner. It is known to be
175+
vulnerable to timing based side channel attacks. use_pkcs1_padding()
176+
results in a fatal error.
177+
178+
Marvin Attack
179+
<https://github.com/tomato42/marvin-toolkit/blob/master/README.md>
151180

152181
use_pkcs1_oaep_padding
153182
Use "EME-OAEP" padding as defined in PKCS #1 v2.0 with SHA-1, MGF1
154183
and an empty encoding parameter. This mode of padding is recommended
155184
for all new applications. It is the default mode used by
156-
"Crypt::OpenSSL::RSA".
185+
"Crypt::OpenSSL::RSA" but is only valid for encryption/decryption.
186+
187+
use_pkcs1_pss_padding
188+
Use RSA-PSS padding as defined in PKCS#1 v2.1. In general, RSA-PSS
189+
should be used as a replacement for RSA-PKCS#1 v1.5. The module
190+
specifies the message digest being requested and the appropriate mgf1
191+
setting and salt length for the digest.
192+
193+
Note: RSA-PSS cannot be used for encryption/decryption and results in
194+
a fatal error. Call use_pkcs1_oaep_padding for encryption operations.
157195

158196
use_sslv23_padding
159197
Use "PKCS #1 v1.5" padding with an SSL-specific modification that
160198
denotes that the server is SSL3 capable.
161199

162200
Not available since OpenSSL 3.
163201

202+
Hash/Digest Methods
164203
use_md5_hash
165204
Use the RFC 1321 MD5 hashing algorithm by Ron Rivest when signing
166205
and verifying messages.

README.md

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Crypt::OpenSSL::RSA - RSA encoding and decoding, using the openSSL libraries
1616
$ciphertext = $rsa->encrypt($plaintext);
1717

1818
$rsa_priv = Crypt::OpenSSL::RSA->new_private_key($key_string);
19-
$plaintext = $rsa->encrypt($ciphertext);
19+
$plaintext = $rsa->decrypt($ciphertext);
2020

2121
$rsa = Crypt::OpenSSL::RSA->generate_key(1024); # or
2222
$rsa = Crypt::OpenSSL::RSA->generate_key(1024, $prime);
@@ -31,6 +31,15 @@ Crypt::OpenSSL::RSA - RSA encoding and decoding, using the openSSL libraries
3131
$signature = $rsa_priv->sign($plaintext);
3232
print "Signed correctly\n" if ($rsa->verify($plaintext, $signature));
3333

34+
# SECURITY
35+
36+
Version 0.35 makes the use of PKCS#1 v1.5 padding a fatal error. It is
37+
very difficult to implement PKCS#1 v1.5 padding securely. If you are still
38+
using RSA in in general, you should be looking at alternative encryption
39+
algorithms. Version 0.36 implements RSA-PSS padding (PKCS#1 v2.1) and makes
40+
setting an invalid padding a fatal error. Note, PKCS1\_OAEP can only be used
41+
for encryption and PKCS1\_PSS can only be used for signing.
42+
3443
# DESCRIPTION
3544

3645
`Crypt::OpenSSL::RSA` provides the ability to RSA encrypt strings which are
@@ -54,6 +63,10 @@ this (never documented) behavior is no longer the case.
5463
The padding is set to PKCS1\_OAEP, but can be changed with the
5564
`use_xxx_padding` methods.
5665

66+
Note, PKCS1\_OAEP can only be used for encryption. You must specifically
67+
call use\_pkcs1\_pss\_padding (or use\_pkcs1\_pss\_padding) prior to signing
68+
operations.
69+
5770
- new\_private\_key
5871

5972
Create a new `Crypt::OpenSSL::RSA` object by loading a private key in
@@ -165,6 +178,18 @@ this (never documented) behavior is no longer the case.
165178

166179
Check the signature on a text.
167180

181+
# Padding Methods
182+
183+
Versions prior to 0.35 allowed using pkcs1 padding for both encryption
184+
and signature operations but has been disabled for security reasons.
185+
186+
While **use\_no\_padding** can be used for encryption or signature operations
187+
**use\_pkcs1\_pss\_padding** is used for signature operations and
188+
**use\_pkcs1\_oaep\_padding** is used for encryption operations.
189+
190+
Version 0.38 sets the appropriate padding for each operation unless
191+
**use\_no\_padding** is called before either operation.
192+
168193
- use\_no\_padding
169194

170195
Use raw RSA encryption. This mode should only be used to implement
@@ -173,15 +198,28 @@ this (never documented) behavior is no longer the case.
173198

174199
- use\_pkcs1\_padding
175200

176-
Use PKCS #1 v1.5 padding. This currently is the most widely used mode
177-
of padding.
201+
PKCS #1 v1.5 padding has been disabled as it is nearly impossible to use this
202+
padding method in a secure manner. It is known to be vulnerable to timing
203+
based side channel attacks. use\_pkcs1\_padding() results in a fatal error.
204+
205+
[Marvin Attack](https://github.com/tomato42/marvin-toolkit/blob/master/README.md)
178206

179207
- use\_pkcs1\_oaep\_padding
180208

181209
Use `EME-OAEP` padding as defined in PKCS #1 v2.0 with SHA-1, MGF1 and
182210
an empty encoding parameter. This mode of padding is recommended for
183211
all new applications. It is the default mode used by
184-
`Crypt::OpenSSL::RSA`.
212+
`Crypt::OpenSSL::RSA` but is only valid for encryption/decryption.
213+
214+
- use\_pkcs1\_pss\_padding
215+
216+
Use `RSA-PSS` padding as defined in PKCS#1 v2.1. In general, RSA-PSS
217+
should be used as a replacement for RSA-PKCS#1 v1.5. The module specifies
218+
the message digest being requested and the appropriate mgf1 setting and
219+
salt length for the digest.
220+
221+
**Note**: RSA-PSS cannot be used for encryption/decryption and results in a
222+
fatal error. Call `use_pkcs1_oaep_padding` for encryption operations.
185223

186224
- use\_sslv23\_padding
187225

@@ -190,6 +228,8 @@ this (never documented) behavior is no longer the case.
190228

191229
Not available since OpenSSL 3.
192230

231+
# Hash/Digest Methods
232+
193233
- use\_md5\_hash
194234

195235
Use the RFC 1321 MD5 hashing algorithm by Ron Rivest when signing and

RSA.pm

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ Crypt::OpenSSL::RSA - RSA encoding and decoding, using the openSSL libraries
8585
Version 0.35 makes the use of PKCS#1 v1.5 padding a fatal error. It is
8686
very difficult to implement PKCS#1 v1.5 padding securely. If you are still
8787
using RSA in in general, you should be looking at alternative encryption
88-
algorithms.
88+
algorithms. Version 0.36 implements RSA-PSS padding (PKCS#1 v2.1) and makes
89+
setting an invalid padding a fatal error. Note, PKCS1_OAEP can only be used
90+
for encryption and PKCS1_PSS can only be used for signing.
8991
9092
=head1 DESCRIPTION
9193
@@ -112,6 +114,10 @@ C<-----BEGIN...-----> and C<-----END...-----> lines.
112114
The padding is set to PKCS1_OAEP, but can be changed with the
113115
C<use_xxx_padding> methods.
114116
117+
Note, PKCS1_OAEP can only be used for encryption. You must specifically
118+
call use_pkcs1_pss_padding (or use_pkcs1_pss_padding) prior to signing
119+
operations.
120+
115121
=item new_private_key
116122
117123
Create a new C<Crypt::OpenSSL::RSA> object by loading a private key in
@@ -235,6 +241,22 @@ Sign a string using the secret (portion of the) key.
235241
236242
Check the signature on a text.
237243
244+
=back
245+
246+
=head1 Padding Methods
247+
248+
Versions prior to 0.35 allowed using pkcs1 padding for both encryption
249+
and signature operations but has been disabled for security reasons.
250+
251+
While B<use_no_padding> can be used for encryption or signature operations
252+
B<use_pkcs1_pss_padding> is used for signature operations and
253+
B<use_pkcs1_oaep_padding> is used for encryption operations.
254+
255+
Version 0.38 sets the appropriate padding for each operation unless
256+
B<use_no_padding> is called before either operation.
257+
258+
=over
259+
238260
=item use_no_padding
239261
240262
Use raw RSA encryption. This mode should only be used to implement
@@ -254,7 +276,7 @@ L<Marvin Attack|https://github.com/tomato42/marvin-toolkit/blob/master/README.md
254276
Use C<EME-OAEP> padding as defined in PKCS #1 v2.0 with SHA-1, MGF1 and
255277
an empty encoding parameter. This mode of padding is recommended for
256278
all new applications. It is the default mode used by
257-
C<Crypt::OpenSSL::RSA>.
279+
C<Crypt::OpenSSL::RSA> but is only valid for encryption/decryption.
258280
259281
=item use_pkcs1_pss_padding
260282
@@ -273,6 +295,12 @@ denotes that the server is SSL3 capable.
273295
274296
Not available since OpenSSL 3.
275297
298+
=back
299+
300+
=head1 Hash/Digest Methods
301+
302+
=over
303+
276304
=item use_md5_hash
277305
278306
Use the RFC 1321 MD5 hashing algorithm by Ron Rivest when signing and

RSA.xs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -339,11 +339,16 @@ SV* rsa_crypt(rsaData* p_rsa, SV* p_from,
339339
CHECK_OPEN_SSL(ctx);
340340

341341
CHECK_OPEN_SSL(init_crypt(ctx) == 1);
342-
CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0);
342+
int crypt_pad = p_rsa->padding;
343+
if (p_rsa->padding != RSA_NO_PADDING) {
344+
crypt_pad = RSA_PKCS1_OAEP_PADDING;
345+
}
346+
CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, crypt_pad) > 0);
343347
CHECK_OPEN_SSL(p_crypt(ctx, NULL, &to_length, from, from_length) == 1);
344348
CHECK_OPEN_SSL(p_crypt(ctx, to, &to_length, from, from_length) == 1);
345349

346350
EVP_PKEY_CTX_free(ctx);
351+
OSSL_LIB_CTX_free(ossllibctx);
347352
#else
348353
to_length = p_crypt(
349354
from_length, from, (unsigned char*) to, p_rsa->rsa, p_rsa->padding);
@@ -980,7 +985,11 @@ sign(p_rsa, text_SV)
980985
CHECK_OPEN_SSL(ctx);
981986
CHECK_OPEN_SSL(EVP_PKEY_sign_init(ctx));
982987
/* FIXME: Issue setting padding in some cases */
983-
CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0);
988+
int sign_pad = p_rsa->padding;
989+
if (p_rsa->padding != RSA_NO_PADDING) {
990+
sign_pad = RSA_PKCS1_PSS_PADDING;
991+
}
992+
CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, sign_pad) > 0);
984993

985994
EVP_MD* md = get_md_bynid(p_rsa->hashMode);
986995
CHECK_OPEN_SSL(md != NULL);
@@ -1000,6 +1009,8 @@ sign(p_rsa, text_SV)
10001009

10011010
CHECK_OPEN_SSL(EVP_PKEY_sign(ctx, signature, &signature_length, digest, get_digest_length(p_rsa->hashMode)) == 1);
10021011
CHECK_OPEN_SSL(signature);
1012+
EVP_MD_free(md);
1013+
EVP_PKEY_CTX_free(ctx);
10031014
#else
10041015
CHECK_OPEN_SSL(RSA_sign(p_rsa->hashMode,
10051016
digest,
@@ -1040,8 +1051,11 @@ PPCODE:
10401051
CHECK_OPEN_SSL(ctx);
10411052
CHECK_OPEN_SSL(EVP_PKEY_verify_init(ctx) == 1);
10421053
/* FIXME: Issue setting padding in some cases */
1043-
CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0);
1044-
1054+
int verify_pad = p_rsa->padding;
1055+
if (p_rsa->padding != RSA_NO_PADDING) {
1056+
verify_pad = RSA_PKCS1_PSS_PADDING;
1057+
}
1058+
CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, verify_pad) > 0);
10451059
EVP_MD* md = get_md_bynid(p_rsa->hashMode);
10461060
CHECK_OPEN_SSL(md != NULL);
10471061

@@ -1073,6 +1087,10 @@ PPCODE:
10731087
CHECK_OPEN_SSL(0);
10741088
break;
10751089
}
1090+
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1091+
EVP_MD_free(md);
1092+
EVP_PKEY_CTX_free(ctx);
1093+
#endif
10761094
}
10771095

10781096
int

0 commit comments

Comments
 (0)