Skip to content

Commit

Permalink
Allow Bytes::Random::Secure instead of Crypt::Random.
Browse files Browse the repository at this point in the history
Also include tests to ensure that the new utility function get_random_bigint
works properly.
  • Loading branch information
bk2204 committed Dec 29, 2012
1 parent a426827 commit 0010163
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 19 deletions.
4 changes: 2 additions & 2 deletions lib/Crypt/OpenPGP.pm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use Crypt::OpenPGP::Plaintext;
use Crypt::OpenPGP::Message;
use Crypt::OpenPGP::PacketFactory;
use Crypt::OpenPGP::Config;
use Crypt::OpenPGP::Util;

use Crypt::OpenPGP::ErrorHandler;
use base qw( Crypt::OpenPGP::ErrorHandler );
Expand Down Expand Up @@ -455,8 +456,7 @@ sub encrypt {
Crypt::OpenPGP::Compressed->errstr);
$ptdata = Crypt::OpenPGP::PacketFactory->save($cdata);
}
require Crypt::Random;
my $key_data = Crypt::Random::makerandom_octet( Length => 32 );
my $key_data = Crypt::OpenPGP::Util::get_random_bytes(32);
my $sym_alg = $param{Cipher} ?
Crypt::OpenPGP::Cipher->alg_id($param{Cipher}) : DEFAULT_CIPHER;
my(@sym_keys);
Expand Down
3 changes: 1 addition & 2 deletions lib/Crypt/OpenPGP/Certificate.pm
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,7 @@ sub lock {
my($passphrase) = @_;
my $cipher = Crypt::OpenPGP::Cipher->new($cert->{cipher});
my $sym_key = $cert->{s2k}->generate($passphrase, $cipher->keysize);
require Crypt::Random;
$cert->{iv} = Crypt::Random::makerandom_octet( Length => 8 );
$cert->{iv} = Crypt::OpenPGP::Util::get_random_bytes(8);
$cipher->init($sym_key, $cert->{iv});
my @sec = $cert->{key}->secret_props;
if ($cert->{version} < 4) {
Expand Down
4 changes: 2 additions & 2 deletions lib/Crypt/OpenPGP/Ciphertext.pm
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package Crypt::OpenPGP::Ciphertext;
use strict;

use Crypt::OpenPGP::Util;
use Crypt::OpenPGP::Cipher;
use Crypt::OpenPGP::Constants qw( DEFAULT_CIPHER
PGP_PKT_ENCRYPTED
Expand All @@ -24,11 +25,10 @@ sub init {
if ((my $key = $param{SymKey}) && (my $data = $param{Data})) {
$enc->{is_mdc} = $param{MDC} || 0;
$enc->{version} = 1;
require Crypt::Random;
my $alg = $param{Cipher} || DEFAULT_CIPHER;
my $cipher = Crypt::OpenPGP::Cipher->new($alg, $key);
my $bs = $cipher->blocksize;
my $pad = Crypt::Random::makerandom_octet( Length => $bs );
my $pad = Crypt::OpenPGP::Util::get_random_bytes($bs);
$pad .= substr $pad, -2, 2;
$enc->{ciphertext} = $cipher->encrypt($pad);
$cipher->sync unless $enc->{is_mdc};
Expand Down
5 changes: 1 addition & 4 deletions lib/Crypt/OpenPGP/Key/Public/ElGamal.pm
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,7 @@ sub gen_k {
my $bits = 198;
my $p_minus1 = $p - 1;

require Crypt::Random;
my $k = Crypt::Random::makerandom( Size => $bits, Strength => 0 );
# We get back a Math::Pari object, but need a Math::BigInt
$k = Math::BigInt->new($k);
my $k = Crypt::OpenPGP::Util::get_random_bigint($bits);
while (1) {
last if Math::BigInt::bgcd($k, $p_minus1) == 1;
$k++;
Expand Down
7 changes: 3 additions & 4 deletions lib/Crypt/OpenPGP/S2k.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use strict;
use Crypt::OpenPGP::Buffer;
use Crypt::OpenPGP::Digest;
use Crypt::OpenPGP::ErrorHandler;
use Crypt::OpenPGP::Util;
use base qw( Crypt::OpenPGP::ErrorHandler );

use vars qw( %TYPES );
Expand Down Expand Up @@ -95,8 +96,7 @@ sub init {
}
else {
$s2k->{hash_alg} = DEFAULT_DIGEST;
require Crypt::Random;
$s2k->{salt} = Crypt::Random::makerandom_octet( Length => 8 );
$s2k->{salt} = Crypt::OpenPGP::Util::get_random_bytes(8);
}
if ($s2k->{hash_alg}) {
$s2k->{hash} = Crypt::OpenPGP::Digest->new($s2k->{hash_alg});
Expand Down Expand Up @@ -130,8 +130,7 @@ sub init {
}
else {
$s2k->{hash_alg} = DEFAULT_DIGEST;
require Crypt::Random;
$s2k->{salt} = Crypt::Random::makerandom_octet( Length => 8 );
$s2k->{salt} = Crypt::OpenPGP::Util::get_random_bytes(8);
$s2k->{count} = 96;
}
if ($s2k->{hash_alg}) {
Expand Down
7 changes: 4 additions & 3 deletions lib/Crypt/OpenPGP/SessionKey.pm
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,12 @@ sub decrypt {

sub _encode {
my $class = shift;
require Crypt::Random;
my($sym_key, $sym_alg, $size) = @_;
my $padlen = "$size" - length($sym_key) - 2 - 2 - 2;
my $pad = Crypt::Random::makerandom_octet( Length => $padlen,
Skip => chr(0) );
my $pad = "\0";
while ($pad =~ tr/\0//) {
$pad = Crypt::OpenPGP::Util::get_random_bytes($padlen);
}
bin2mp(pack 'na*na*n', 2, $pad, $sym_alg, $sym_key,
unpack('%16C*', $sym_key));
}
Expand Down
33 changes: 33 additions & 0 deletions lib/Crypt/OpenPGP/Util.pm
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,39 @@ sub _ensure_bigint {
return $num;
}
sub get_random_bytes {
my $length = shift;
if (eval 'require Crypt::Random; 1;') {
return Crypt::Random::makerandom_octet( Length => $length);
}
elsif (eval 'require Bytes::Random::Secure; 1;') {
return Bytes::Random::Secure::random_bytes($length);
}
else {
die "No random source available!";
}
}
sub get_random_bigint {
my $bits = shift;
if (eval 'require Crypt::Random; 1;') {
my $pari = Crypt::Random::makerandom( Size => $bits, Strength => 0 );
return Math::BigInt->new($pari);
}
elsif (eval 'require Bytes::Random::Secure; 1;') {
my $hex = Bytes::Random::Secure::random_bytes_hex(($bits + 7) / 8);
my $val = Math::BigInt->new("0x$hex");
# Get exactly the correct number of bits.
$val->brsft(8 - ($bits & 7)) if ($bits & 7);
# Make sure the top bit is set.
$val->bior(Math::BigInt->bone->blsft($bits-1));
return $val;
}
else {
die "No random source available!";
}
}
1;
__END__
Expand Down
13 changes: 11 additions & 2 deletions t/01-util.t
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use strict;
use Test::More tests => 41;
use Test::More tests => 63;

use Math::BigInt;
use Crypt::OpenPGP::Util qw( bin2bigint bigint2bin bitsize mod_exp mod_inverse );
Expand Down Expand Up @@ -59,4 +59,13 @@ is $num, $n4, 'mod_exp is correct';
("34093840983", "23509283509", "7281956166");
$num = mod_inverse( $n1, $n2 );
is $num, $n3, 'mod_inverse gives expected result';
is 1, ( $n1 * $num ) % $n2, 'mod_inverse verified';
is 1, ( $n1 * $num ) % $n2, 'mod_inverse verified';

for my $bits (190..200) {
my $val = Crypt::OpenPGP::Util::get_random_bigint($bits);
my $topbit = Math::BigInt->new("0b1" . ("0" x ($bits-1)));
$topbit->band($val);
ok !$topbit->is_zero, "top bit is set for $bits-bit number";
$val->brsft($bits);
ok $val->is_zero, "number is exactly $bits bits";
}

0 comments on commit 0010163

Please sign in to comment.