The Perl and Raku Conference 2025: Greenville, South Carolina - June 27-29 Learn more

# ABSTRACT: get random bytes from the system
use v5.20;
use Exporter qw( import );
use FFI::Platypus 2.00;
use experimental qw( signatures );
use constant GRND_NONBLOCK => 0x0001;
use constant GRND_RANDOM => 0x0002;
our @EXPORT_OK = qw( GRND_RANDOM GRND_NONBLOCK getrandom );
our $VERSION = 'v0.1.1';
sub getrandom( $size, $opts = 0 ) {
state $ffi = FFI::Platypus->new(
api => 2,
lib => undef, # libc
);
state $random = $ffi->function( getrandom => [ 'string', 'size_t', 'int' ] => 'size_t' );
my $buffer = "\0" x $size;
my $res = $random->call( $buffer, $size, $opts );
return $res != -1 ? $buffer : undef;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Sys::GetRandom::FFI - get random bytes from the system
=head1 VERSION
version v0.1.1
=head1 SYNOPSIS
use Sys::GetRandom::FFI qw( getrandom GRND_RANDOM GRND_NONBLOCK );
my $bytes = getrandom( $size, GRND_RANDOM | GRND_NONBLOCK );
if ( defined($bytes) ) {
...
}
=head1 DESCRIPTION
This is a proof-of-concept module for calling the L<getrandom(2)> system function via L<FFI::Platypus>.
=head1 EXPORTS
=head2 getrandom
my $bytes = getrandom( $size, $options );
This will return a scalar of up to C<$size> bytes, or C<undef> if there was an error.
It may return less than C<$size> bytes if L</GRND_RANDOM> was given as an option and there was less entropy or or if the
entropy pool has not been initialised, or if it was interrupted by a signal when C<$size> is over 256.
The C<$options> are optional.
=head2 GRND_RANDOM
When this bit is set, it will read from F</dev/random> instead of F</dev/urandom>.
=head2 GRND_NONBLOCK
This will exit with C<undef> when there are no random bytes available.
=head1 SEE ALSO
=over 4
=item L<getrandom(2)>
=item L<Sys::GetRandom>
This is an XS module that calls L<getrandom(2)> directly. It has a slightly different interface but is faster.
=item L<Sys::GetRandom::PP>
This is a pure-Perl module that makes syscalls to L<getrandom(2)>.
=item L<Rand::URandom>
This is a pure-Perl module that makes syscalls to L<getrandom(2)>, but falls back to reading from F</dev/urandom>.
=item L<Crypt::URandom>
This is a pure-Perl module that reads data from F</dev/urandom>. It also uses L<Win32::API> to read random bytes on
Windows.
=item L<Random::Simple>
This is another module that reads data from F</dev/urandom> or calls L<getrandom(2)>.
=back
=head1 SUPPORT FOR OLDER PERL VERSIONS
This module requires Perl v5.20 or later.
Future releases may only support Perl versions released in the last ten (10) years.
=head1 SOURCE
The development version is on github at L<https://github.com/robrwo/perl-Sys-GetRandom-FFI>
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=head2 Reporting Security Vulnerabilities
Security issues should not be reported on the bugtracker website. Please see F<SECURITY.md> for instructions how to
report security vulnerabilities
=head1 AUTHOR
Robert Rothenberg <rrwo@cpan.org>
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2024 by Robert Rothenberg <rrwo@cpan.org>.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)
=cut