package Sys::GetRandom::FFI; # ABSTRACT: get random bytes from the system use v5.20; use warnings; 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> and may be cloned from L<git://github.com/robrwo/perl-Sys-GetRandom-FFI.git> =head1 BUGS Please report any bugs or feature requests on the bugtracker website L<https://github.com/robrwo/perl-Sys-GetRandom-FFI/issues> 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