Skip to content

Commit 9493040

Browse files
authored
Merge PR-9410 from sverker/crypto/fips-version/OTP-19487
GH-9366
2 parents 661f25a + 494811c commit 9493040

File tree

4 files changed

+61
-13
lines changed

4 files changed

+61
-13
lines changed

lib/crypto/c_src/crypto.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ static ErlNifFunc nif_funcs[] = {
139139
};
140140

141141
#ifdef HAS_3_0_API
142+
# ifdef FIPS_SUPPORT
143+
OSSL_PROVIDER *fips_provider;
144+
# endif
142145
OSSL_PROVIDER *prov[MAX_NUM_PROVIDERS];
143146
int prov_cnt;
144147
#endif
@@ -255,9 +258,7 @@ static int initialize(ErlNifEnv* env, ERL_NIF_TERM load_info)
255258
#ifdef HAS_3_0_API
256259
prov_cnt = 0;
257260
# ifdef FIPS_SUPPORT
258-
if ((prov[prov_cnt] = OSSL_PROVIDER_load(NULL, "fips"))) {
259-
prov_cnt++;
260-
}
261+
fips_provider = OSSL_PROVIDER_load(NULL, "fips");
261262
# endif
262263
if (!(prov[prov_cnt++] = OSSL_PROVIDER_load(NULL, "default"))) {
263264
ret = __LINE__; goto done;
@@ -392,6 +393,11 @@ static void unload(ErlNifEnv* env, void* priv_data)
392393
destroy_engine_mutex(env);
393394

394395
#ifdef HAS_3_0_API
396+
# ifdef FIPS_SUPPORT
397+
if (fips_provider) {
398+
OSSL_PROVIDER_unload(fips_provider);
399+
}
400+
# endif
395401
while (prov_cnt > 0) {
396402
OSSL_PROVIDER_unload(prov[--prov_cnt]);
397403
}

lib/crypto/c_src/info.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,10 @@ const char* resource_name(const char *name, ErlNifBinary* buf)
107107

108108
ERL_NIF_TERM info_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
109109
{/* () */
110-
ERL_NIF_TERM keys[5], vals[5];
110+
#if defined(HAS_3_0_API) && defined(FIPS_SUPPORT)
111+
extern OSSL_PROVIDER *fips_provider;
112+
#endif
113+
ERL_NIF_TERM keys[6], vals[6];
111114
ERL_NIF_TERM ret;
112115
size_t cnt;
113116
int ok;
@@ -125,13 +128,28 @@ ERL_NIF_TERM info_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
125128
#endif
126129
keys[3] = enif_make_atom(env, "cryptolib_version_linked");
127130
vals[3] = enif_make_string(env, OpenSSL_version(OPENSSL_VERSION), ERL_NIF_LATIN1);
128-
#ifdef HAS_3_0_API
129-
keys[4] = enif_make_atom(env, "fips_provider_available");
130-
vals[4] = OSSL_PROVIDER_available(NULL, "fips") ? atom_true : atom_false;
131-
cnt = 5;
132-
#else
133131
cnt = 4;
132+
#ifdef HAS_3_0_API
133+
keys[cnt] = enif_make_atom(env, "fips_provider_available");
134+
vals[cnt] = OSSL_PROVIDER_available(NULL, "fips") ? atom_true : atom_false;
135+
cnt++;
136+
# ifdef FIPS_SUPPORT
137+
if (fips_provider) {
138+
const char *build_info = NULL;
139+
OSSL_PARAM request[] = {
140+
{ "buildinfo", OSSL_PARAM_UTF8_PTR, &build_info, 0, 0 },
141+
{ NULL, 0, NULL, 0, 0 }
142+
};
143+
if (!OSSL_PROVIDER_get_params(fips_provider, request)) {
144+
build_info = "Not available";
145+
}
146+
keys[cnt] = enif_make_atom(env, "fips_provider_buildinfo");
147+
vals[cnt] = enif_make_string(env, build_info, ERL_NIF_UTF8);
148+
cnt++;
149+
}
150+
# endif
134151
#endif
152+
ASSERT(cnt <= sizeof(keys)/sizeof(keys[0]));
135153
ok = enif_make_map_from_arrays(env, keys, vals, cnt, &ret);
136154
ASSERT(ok); (void)ok;
137155

lib/crypto/src/crypto.erl

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -918,19 +918,24 @@ Example:
918918
cryptolib_version_compiled => "OpenSSL 3.0.0 7 sep 2021",
919919
cryptolib_version_linked => "OpenSSL 3.0.0 7 sep 2021",
920920
link_type => dynamic,
921-
otp_crypto_version => "5.0.2"}
921+
otp_crypto_version => "5.0.2",
922+
fips_provider_available => true,
923+
fips_provider_buildinfo => "3.0.0"}
922924
2>
923925
```
924926

925-
More association types than documented may be present in the map.
927+
More association types than documented may be present in the map. Some of the
928+
associations (like fips) may be absent if not supported.
926929
""".
927930
-doc(#{title => <<"Utility Functions">>,
928931
since => <<"OTP 24.2">>}).
929932
-spec info() -> #{compile_type := normal | debug | valgrind | asan,
930-
cryptolib_version_compiled => string() | undefined,
933+
cryptolib_version_compiled := string() | undefined,
931934
cryptolib_version_linked := string(),
932935
link_type := dynamic | static,
933-
otp_crypto_version := string()
936+
otp_crypto_version := string(),
937+
fips_provider_available => boolean(),
938+
fips_provider_buildinfo => string()
934939
}.
935940
info() ->
936941
(info_nif())#{otp_crypto_version => crypto:version()}.

lib/crypto/test/crypto_SUITE.erl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4920,13 +4920,15 @@ try_enable_fips_mode(Config) ->
49204920
FIPSConfig = [{fips, true} | Config],
49214921
case crypto:info_fips() of
49224922
enabled ->
4923+
check_fips_provider(),
49234924
FIPSConfig;
49244925
not_enabled ->
49254926
%% Erlang/crypto configured with --enable-fips
49264927
case crypto:enable_fips_mode(true) of
49274928
true ->
49284929
%% and also the cryptolib is fips enabled
49294930
enabled = crypto:info_fips(),
4931+
check_fips_provider(),
49304932
FIPSConfig;
49314933
false ->
49324934
try
@@ -4947,6 +4949,23 @@ try_enable_fips_mode(Config) ->
49474949
{skip, "FIPS mode not supported"}
49484950
end.
49494951

4952+
check_fips_provider() ->
4953+
case have_provider_support() of
4954+
true ->
4955+
case crypto:info() of
4956+
#{fips_provider_available := true,
4957+
fips_provider_buildinfo := BI} when is_list(BI) ->
4958+
ok
4959+
end;
4960+
false ->
4961+
ok
4962+
end.
4963+
4964+
have_provider_support() ->
4965+
[{_, PackedVsn, _}] = crypto:info_lib(),
4966+
MajorVsn = (PackedVsn bsr 28),
4967+
MajorVsn >= 3.
4968+
49504969
pbkdf2_hmac() ->
49514970
[{doc, "Test the pbkdf2_hmac function"}].
49524971
pbkdf2_hmac(Config) when is_list(Config) ->

0 commit comments

Comments
 (0)