Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 43 additions & 4 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ SYNOPSIS
$ciphertext = $rsa->encrypt($plaintext);

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

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

SECURITY
Version 0.35 makes the use of PKCS#1 v1.5 padding a fatal error. It is
very difficult to implement PKCS#1 v1.5 padding securely. If you are
still using RSA in in general, you should be looking at alternative
encryption algorithms. Version 0.36 implements RSA-PSS padding (PKCS#1
v2.1) and makes setting an invalid padding a fatal error. Note,
PKCS1_OAEP can only be used for encryption and PKCS1_PSS can only be
used for signing.

DESCRIPTION
"Crypt::OpenSSL::RSA" provides the ability to RSA encrypt strings which
are somewhat shorter than the block size of a key. It also allows for
Expand All @@ -48,6 +57,10 @@ Class Methods
The padding is set to PKCS1_OAEP, but can be changed with the
"use_xxx_padding" methods.

Note, PKCS1_OAEP can only be used for encryption. You must
specifically call use_pkcs1_pss_padding (or use_pkcs1_pss_padding)
prior to signing operations.

new_private_key
Create a new "Crypt::OpenSSL::RSA" object by loading a private key
in from an string containing the Base64/DER encoding of the PKCS1
Expand Down Expand Up @@ -140,27 +153,53 @@ Instance Methods
verify
Check the signature on a text.

Padding Methods
Versions prior to 0.35 allowed using pkcs1 padding for both encryption
and signature operations but has been disabled for security reasons.

While use_no_padding can be used for encryption or signature operations
use_pkcs1_pss_padding is used for signature operations and
use_pkcs1_oaep_padding is used for encryption operations.

Version 0.38 sets the appropriate padding for each operation unless
use_no_padding is called before either operation.

use_no_padding
Use raw RSA encryption. This mode should only be used to implement
cryptographically sound padding modes in the application code.
Encrypting user data directly with RSA is insecure.

use_pkcs1_padding
Use PKCS #1 v1.5 padding. This currently is the most widely used
mode of padding.
PKCS #1 v1.5 padding has been disabled as it is nearly impossible to
use this padding method in a secure manner. It is known to be
vulnerable to timing based side channel attacks. use_pkcs1_padding()
results in a fatal error.

Marvin Attack
<https://github.com/tomato42/marvin-toolkit/blob/master/README.md>

use_pkcs1_oaep_padding
Use "EME-OAEP" padding as defined in PKCS #1 v2.0 with SHA-1, MGF1
and an empty encoding parameter. This mode of padding is recommended
for all new applications. It is the default mode used by
"Crypt::OpenSSL::RSA".
"Crypt::OpenSSL::RSA" but is only valid for encryption/decryption.

use_pkcs1_pss_padding
Use RSA-PSS padding as defined in PKCS#1 v2.1. In general, RSA-PSS
should be used as a replacement for RSA-PKCS#1 v1.5. The module
specifies the message digest being requested and the appropriate mgf1
setting and salt length for the digest.

Note: RSA-PSS cannot be used for encryption/decryption and results in
a fatal error. Call use_pkcs1_oaep_padding for encryption operations.

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

Not available since OpenSSL 3.

Hash/Digest Methods
use_md5_hash
Use the RFC 1321 MD5 hashing algorithm by Ron Rivest when signing
and verifying messages.
Expand Down
48 changes: 44 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Crypt::OpenSSL::RSA - RSA encoding and decoding, using the openSSL libraries
$ciphertext = $rsa->encrypt($plaintext);

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

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

# SECURITY

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

# DESCRIPTION

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

Note, PKCS1\_OAEP can only be used for encryption. You must specifically
call use\_pkcs1\_pss\_padding (or use\_pkcs1\_pss\_padding) prior to signing
operations.

- new\_private\_key

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

Check the signature on a text.

# Padding Methods

Versions prior to 0.35 allowed using pkcs1 padding for both encryption
and signature operations but has been disabled for security reasons.

While **use\_no\_padding** can be used for encryption or signature operations
**use\_pkcs1\_pss\_padding** is used for signature operations and
**use\_pkcs1\_oaep\_padding** is used for encryption operations.

Version 0.38 sets the appropriate padding for each operation unless
**use\_no\_padding** is called before either operation.

- use\_no\_padding

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

- use\_pkcs1\_padding

Use PKCS #1 v1.5 padding. This currently is the most widely used mode
of padding.
PKCS #1 v1.5 padding has been disabled as it is nearly impossible to use this
padding method in a secure manner. It is known to be vulnerable to timing
based side channel attacks. use\_pkcs1\_padding() results in a fatal error.

[Marvin Attack](https://github.com/tomato42/marvin-toolkit/blob/master/README.md)

- use\_pkcs1\_oaep\_padding

Use `EME-OAEP` padding as defined in PKCS #1 v2.0 with SHA-1, MGF1 and
an empty encoding parameter. This mode of padding is recommended for
all new applications. It is the default mode used by
`Crypt::OpenSSL::RSA`.
`Crypt::OpenSSL::RSA` but is only valid for encryption/decryption.

- use\_pkcs1\_pss\_padding

Use `RSA-PSS` padding as defined in PKCS#1 v2.1. In general, RSA-PSS
should be used as a replacement for RSA-PKCS#1 v1.5. The module specifies
the message digest being requested and the appropriate mgf1 setting and
salt length for the digest.

**Note**: RSA-PSS cannot be used for encryption/decryption and results in a
fatal error. Call `use_pkcs1_oaep_padding` for encryption operations.

- use\_sslv23\_padding

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

Not available since OpenSSL 3.

# Hash/Digest Methods

- use\_md5\_hash

Use the RFC 1321 MD5 hashing algorithm by Ron Rivest when signing and
Expand Down
32 changes: 30 additions & 2 deletions RSA.pm
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ Crypt::OpenSSL::RSA - RSA encoding and decoding, using the openSSL libraries
Version 0.35 makes the use of PKCS#1 v1.5 padding a fatal error. It is
very difficult to implement PKCS#1 v1.5 padding securely. If you are still
using RSA in in general, you should be looking at alternative encryption
algorithms.
algorithms. Version 0.36 implements RSA-PSS padding (PKCS#1 v2.1) and makes
setting an invalid padding a fatal error. Note, PKCS1_OAEP can only be used
for encryption and PKCS1_PSS can only be used for signing.

=head1 DESCRIPTION

Expand All @@ -112,6 +114,10 @@ C<-----BEGIN...-----> and C<-----END...-----> lines.
The padding is set to PKCS1_OAEP, but can be changed with the
C<use_xxx_padding> methods.

Note, PKCS1_OAEP can only be used for encryption. You must specifically
call use_pkcs1_pss_padding (or use_pkcs1_pss_padding) prior to signing
operations.

=item new_private_key

Create a new C<Crypt::OpenSSL::RSA> object by loading a private key in
Expand Down Expand Up @@ -235,6 +241,22 @@ Sign a string using the secret (portion of the) key.

Check the signature on a text.

=back

=head1 Padding Methods

Versions prior to 0.35 allowed using pkcs1 padding for both encryption
and signature operations but has been disabled for security reasons.

While B<use_no_padding> can be used for encryption or signature operations
B<use_pkcs1_pss_padding> is used for signature operations and
B<use_pkcs1_oaep_padding> is used for encryption operations.

Version 0.38 sets the appropriate padding for each operation unless
B<use_no_padding> is called before either operation.

=over

=item use_no_padding

Use raw RSA encryption. This mode should only be used to implement
Expand All @@ -254,7 +276,7 @@ L<Marvin Attack|https://github.com/tomato42/marvin-toolkit/blob/master/README.md
Use C<EME-OAEP> padding as defined in PKCS #1 v2.0 with SHA-1, MGF1 and
an empty encoding parameter. This mode of padding is recommended for
all new applications. It is the default mode used by
C<Crypt::OpenSSL::RSA>.
C<Crypt::OpenSSL::RSA> but is only valid for encryption/decryption.

=item use_pkcs1_pss_padding

Expand All @@ -273,6 +295,12 @@ denotes that the server is SSL3 capable.

Not available since OpenSSL 3.

=back

=head1 Hash/Digest Methods

=over

=item use_md5_hash

Use the RFC 1321 MD5 hashing algorithm by Ron Rivest when signing and
Expand Down
26 changes: 22 additions & 4 deletions RSA.xs
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,16 @@ SV* rsa_crypt(rsaData* p_rsa, SV* p_from,
CHECK_OPEN_SSL(ctx);

CHECK_OPEN_SSL(init_crypt(ctx) == 1);
CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0);
int crypt_pad = p_rsa->padding;
if (p_rsa->padding != RSA_NO_PADDING) {
crypt_pad = RSA_PKCS1_OAEP_PADDING;
}
CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, crypt_pad) > 0);
CHECK_OPEN_SSL(p_crypt(ctx, NULL, &to_length, from, from_length) == 1);
CHECK_OPEN_SSL(p_crypt(ctx, to, &to_length, from, from_length) == 1);

EVP_PKEY_CTX_free(ctx);
OSSL_LIB_CTX_free(ossllibctx);
#else
to_length = p_crypt(
from_length, from, (unsigned char*) to, p_rsa->rsa, p_rsa->padding);
Expand Down Expand Up @@ -980,7 +985,11 @@ sign(p_rsa, text_SV)
CHECK_OPEN_SSL(ctx);
CHECK_OPEN_SSL(EVP_PKEY_sign_init(ctx));
/* FIXME: Issue setting padding in some cases */
CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0);
int sign_pad = p_rsa->padding;
if (p_rsa->padding != RSA_NO_PADDING) {
sign_pad = RSA_PKCS1_PSS_PADDING;
}
CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, sign_pad) > 0);

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

CHECK_OPEN_SSL(EVP_PKEY_sign(ctx, signature, &signature_length, digest, get_digest_length(p_rsa->hashMode)) == 1);
CHECK_OPEN_SSL(signature);
EVP_MD_free(md);
EVP_PKEY_CTX_free(ctx);
#else
CHECK_OPEN_SSL(RSA_sign(p_rsa->hashMode,
digest,
Expand Down Expand Up @@ -1040,8 +1051,11 @@ PPCODE:
CHECK_OPEN_SSL(ctx);
CHECK_OPEN_SSL(EVP_PKEY_verify_init(ctx) == 1);
/* FIXME: Issue setting padding in some cases */
CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0);

int verify_pad = p_rsa->padding;
if (p_rsa->padding != RSA_NO_PADDING) {
verify_pad = RSA_PKCS1_PSS_PADDING;
}
CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, verify_pad) > 0);
EVP_MD* md = get_md_bynid(p_rsa->hashMode);
CHECK_OPEN_SSL(md != NULL);

Expand Down Expand Up @@ -1073,6 +1087,10 @@ PPCODE:
CHECK_OPEN_SSL(0);
break;
}
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_MD_free(md);
EVP_PKEY_CTX_free(ctx);
#endif
}

int
Expand Down
Loading
Loading