+=over 4
+
+=item B<openssl_versions>
+
+Returns a list of two version numbers, the first representing the build
+version, the second representing the library version. See opensslv.h for
+more information on those numbers.
+
+=back
+
+=cut
+
+my @versions = ();
+sub openssl_versions {
+ unless (@versions) {
+ my %lines =
+ map { s/\R$//;
+ /^(.*): (.*)$/;
+ $1 => $2 }
+ run(test(['versions']), capture => 1);
+ @versions = ( $lines{'Build version'}, $lines{'Library version'} );
+ }
+ return @versions;
+}
+
+=over 4
+
+=item B<ok_nofips EXPR, TEST_NAME>
+
+C<ok_nofips> is equivalent to using C<ok> when the environment variable
+C<FIPS_MODE> is undefined, otherwise it is equivalent to C<not ok>. This can be
+used for C<ok> tests that must fail when testing a FIPS provider. The parameters
+are the same as used by C<ok> which is an expression EXPR followed by the test
+description TEST_NAME.
+
+An example:
+
+ ok_nofips(run(app(["md5.pl"])), "md5 should fail in fips mode");
+
+=item B<is_nofips EXPR1, EXPR2, TEST_NAME>
+
+C<is_nofips> is equivalent to using C<is> when the environment variable
+C<FIPS_MODE> is undefined, otherwise it is equivalent to C<isnt>. This can be
+used for C<is> tests that must fail when testing a FIPS provider. The parameters
+are the same as used by C<is> which has 2 arguments EXPR1 and EXPR2 that can be
+compared using eq or ne, followed by a test description TEST_NAME.
+
+An example:
+
+ is_nofips(ultimate_answer(), 42, "Meaning of Life");
+
+=item B<isnt_nofips EXPR1, EXPR2, TEST_NAME>
+
+C<isnt_nofips> is equivalent to using C<isnt> when the environment variable
+C<FIPS_MODE> is undefined, otherwise it is equivalent to C<is>. This can be
+used for C<isnt> tests that must fail when testing a FIPS provider. The
+parameters are the same as used by C<isnt> which has 2 arguments EXPR1 and EXPR2
+that can be compared using ne or eq, followed by a test description TEST_NAME.
+
+An example:
+
+ isnt_nofips($foo, '', "Got some foo");
+
+=back
+
+=cut
+
+sub ok_nofips {
+ return ok(!$_[0], @_[1..$#_]) if defined $ENV{FIPS_MODE};
+ return ok($_[0], @_[1..$#_]);
+}
+
+sub is_nofips {
+ return isnt($_[0], $_[1], @_[2..$#_]) if defined $ENV{FIPS_MODE};
+ return is($_[0], $_[1], @_[2..$#_]);
+}
+
+sub isnt_nofips {
+ return is($_[0], $_[1], @_[2..$#_]) if defined $ENV{FIPS_MODE};
+ return isnt($_[0], $_[1], @_[2..$#_]);
+}
+