Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a FIPS provider and implement SHA256 in it #8537

Closed
wants to merge 12 commits into from
Closed
1 change: 1 addition & 0 deletions Configurations/shared-info.pl
Expand Up @@ -32,6 +32,7 @@ sub detect_gnu_cc {
return {
%{$shared_info{'gnu-shared'}},
shared_defflag => '-Wl,--version-script=',
dso_ldflags => '-z defs',
};
},
'bsd-gcc-shared' => sub { return $shared_info{'linux-shared'}; },
Expand Down
7 changes: 5 additions & 2 deletions Configure
Expand Up @@ -369,6 +369,7 @@ my @disablables = (
"err",
"external-tests",
"filenames",
"fips",
"fuzz-libfuzzer",
"fuzz-afl",
"gost",
Expand Down Expand Up @@ -512,6 +513,8 @@ my @disable_cascades = (
# or modules.
"pic" => [ "shared", "module" ],

"module" => [ "fips" ],

"engine" => [ grep /eng$/, @disablables ],
"hw" => [ "padlockeng" ],

Expand Down Expand Up @@ -1221,8 +1224,8 @@ foreach my $what (sort keys %disabled) {

$config{options} .= " no-$what";

if (!grep { $what eq $_ } ( 'buildtest-c++', 'threads', 'shared', 'module',
'pic', 'dynamic-engine', 'makedepend',
if (!grep { $what eq $_ } ( 'buildtest-c++', 'fips', 'threads', 'shared',
'module', 'pic', 'dynamic-engine', 'makedepend',
'zlib-dynamic', 'zlib', 'sse2' )) {
(my $WHAT = uc $what) =~ s|-|_|g;
my $skipdir = $what;
Expand Down
3 changes: 3 additions & 0 deletions INSTALL
Expand Up @@ -394,6 +394,9 @@
Don't compile in filename and line number information (e.g.
for errors and memory allocation).

no-fips
Don't compile the FIPS module

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it should generate the OPENSSL_NO_FIPS macro, though. That will just add confusion, 'cause that's not a library option.

There's this section in Configure that has a selection of config options that shouldn't end up as C macros of that form, 'fips' should be added there:

openssl/Configure

Lines 1224 to 1226 in e321ba2

if (!grep { $what eq $_ } ( 'buildtest-c++', 'threads', 'shared', 'module',
'pic', 'dynamic-engine', 'makedepend',
'zlib-dynamic', 'zlib', 'sse2' )) {

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it should generate the OPENSSL_NO_FIPS macro, though. That will just add confusion, 'cause that's not a library option.

I guess I don't understand that argument. It's something that we want to be able to write conditional code on (as evidenced by the fact I've used it already in the tests) - so why would we suppress the macro generation?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm. Thinking about this more - I guess this is about whether it is appropriate to have the macro in opensslconf.h (a public header file). Is that it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly

enable-fuzz-libfuzzer, enable-fuzz-afl
Build with support for fuzzing using either libfuzzer or AFL.
These are developer options only. They may not work on all
Expand Down
5 changes: 5 additions & 0 deletions crypto/build.info
Expand Up @@ -21,6 +21,11 @@ SOURCE[../libcrypto]=\
trace.c provider.c params.c \
{- $target{cpuid_asm_src} -} {- $target{uplink_aux_src} -}

# FIPS module
SOURCE[../providers/fips]=\
cryptlib.c mem.c mem_clr.c params.c


levitte marked this conversation as resolved.
Show resolved Hide resolved
DEPEND[cversion.o]=buildinf.h
GENERATE[buildinf.h]=../util/mkbuildinf.pl "$(CC) $(LIB_CFLAGS) $(CPPFLAGS_Q)" "$(PLATFORM)"
DEPEND[buildinf.h]=../configdata.pm
Expand Down
12 changes: 6 additions & 6 deletions crypto/mem.c
Expand Up @@ -14,7 +14,7 @@
#include <stdlib.h>
#include <limits.h>
#include <openssl/crypto.h>
#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
#if !defined(OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE) && !defined(FIPS_MODE)
# include <execinfo.h>
#endif

Expand All @@ -30,7 +30,7 @@ static void *(*realloc_impl)(void *, size_t, const char *, int)
static void (*free_impl)(void *, const char *, int)
= CRYPTO_free;

#ifndef OPENSSL_NO_CRYPTO_MDEBUG
#if !defined(OPENSSL_NO_CRYPTO_MDEBUG) && !defined(FIPS_MODE)
# include "internal/tsan_assist.h"

static TSAN_QUALIFIER int malloc_count;
Expand Down Expand Up @@ -94,7 +94,7 @@ void CRYPTO_get_mem_functions(
*f = free_impl;
}

#ifndef OPENSSL_NO_CRYPTO_MDEBUG
#if !defined(OPENSSL_NO_CRYPTO_MDEBUG) && !defined(FIPS_MODE)
void CRYPTO_get_alloc_counts(int *mcount, int *rcount, int *fcount)
{
if (mcount != NULL)
Expand Down Expand Up @@ -209,7 +209,7 @@ void *CRYPTO_malloc(size_t num, const char *file, int line)
*/
allow_customize = 0;
}
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
#if !defined(OPENSSL_NO_CRYPTO_MDEBUG) && !defined(FIPS_MODE)
if (call_malloc_debug) {
CRYPTO_mem_debug_malloc(NULL, num, 0, file, line);
ret = malloc(num);
Expand Down Expand Up @@ -250,7 +250,7 @@ void *CRYPTO_realloc(void *str, size_t num, const char *file, int line)
return NULL;
}

#ifndef OPENSSL_NO_CRYPTO_MDEBUG
#if !defined(OPENSSL_NO_CRYPTO_MDEBUG) && !defined(FIPS_MODE)
if (call_malloc_debug) {
void *ret;
CRYPTO_mem_debug_realloc(str, NULL, num, 0, file, line);
Expand Down Expand Up @@ -300,7 +300,7 @@ void CRYPTO_free(void *str, const char *file, int line)
return;
}

#ifndef OPENSSL_NO_CRYPTO_MDEBUG
#if !defined(OPENSSL_NO_CRYPTO_MDEBUG) && !defined(FIPS_MODE)
if (call_malloc_debug) {
CRYPTO_mem_debug_free(str, 0, file, line);
free(str);
Expand Down
8 changes: 8 additions & 0 deletions crypto/params.c
Expand Up @@ -348,6 +348,13 @@ OSSL_PARAM OSSL_PARAM_construct_size_t(const char *key, size_t *buf,
return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
sizeof(size_t), rsize); }

#ifndef FIPS_MODE
/*
* TODO(3.0): Make this available in FIPS mode.
*
* Temporarily we don't include these functions in FIPS mode to avoid pulling
* in the entire BN sub-library into the module at this point.
*/
int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val)
{
BIGNUM *b;
Expand Down Expand Up @@ -387,6 +394,7 @@ OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER,
buf, bsize, rsize);
}
#endif

int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val)
{
Expand Down
2 changes: 2 additions & 0 deletions crypto/sha/build.info
Expand Up @@ -3,6 +3,8 @@ SOURCE[../../libcrypto]=\
sha1dgst.c sha1_one.c sha256.c sha512.c {- $target{sha1_asm_src} -} \
{- $target{keccak1600_asm_src} -}

SOURCE[../../providers/fips]= sha256.c

GENERATE[sha1-586.s]=asm/sha1-586.pl \
$(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR)
DEPEND[sha1-586.s]=../perlasm/x86asm.pl
Expand Down
11 changes: 11 additions & 0 deletions providers/build.info
@@ -1 +1,12 @@
SUBDIRS=common default

IF[{- !$disabled{fips} -}]
SUBDIRS=fips
MODULES=fips
IF[{- defined $target{shared_defflag} -}]
SOURCE[fips]=fips.ld
GENERATE[fips.ld]=../util/providers.num
ENDIF
INCLUDE[fips]=.. ../include ../crypto/include
DEFINE[fips]=FIPS_MODE
ENDIF
4 changes: 3 additions & 1 deletion providers/common/digests/build.info
@@ -1,3 +1,5 @@
LIBS=../../../libcrypto
SOURCE[../../../libcrypto]=\
sha2.c

SOURCE[../../fips]=\
sha2.c
2 changes: 2 additions & 0 deletions providers/fips/build.info
@@ -0,0 +1,2 @@

SOURCE[../fips]=fipsprov.c
99 changes: 99 additions & 0 deletions providers/fips/fipsprov.c
@@ -0,0 +1,99 @@
/*
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/

#include <string.h>
#include <stdio.h>
#include <openssl/core.h>
#include <openssl/core_numbers.h>
#include <openssl/core_names.h>
#include <openssl/params.h>

/* Functions provided by the core */
static OSSL_core_get_param_types_fn *c_get_param_types = NULL;
static OSSL_core_get_params_fn *c_get_params = NULL;

/* Parameters we provide to the core */
static const OSSL_ITEM fips_param_types[] = {
{ OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_NAME },
{ OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_VERSION },
{ OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_BUILDINFO },
{ 0, NULL }
};

static const OSSL_ITEM *fips_get_param_types(const OSSL_PROVIDER *prov)
{
return fips_param_types;
}

static int fips_get_params(const OSSL_PROVIDER *prov,
const OSSL_PARAM params[])
{
const OSSL_PARAM *p;

p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_NAME);
if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "OpenSSL FIPS Provider"))
return 0;
p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_VERSION);
if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR))
return 0;
p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_BUILDINFO);
if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_FULL_VERSION_STR))
return 0;

return 1;
}

extern const OSSL_DISPATCH sha256_functions[];
paulidale marked this conversation as resolved.
Show resolved Hide resolved

static const OSSL_ALGORITHM fips_digests[] = {
{ "SHA256", "fips=yes", sha256_functions },
levitte marked this conversation as resolved.
Show resolved Hide resolved
{ NULL, NULL, NULL }
};

static const OSSL_ALGORITHM *fips_query(OSSL_PROVIDER *prov,
int operation_id,
int *no_cache)
{
*no_cache = 0;
switch (operation_id) {
case OSSL_OP_DIGEST:
return fips_digests;
}
return NULL;
}

/* Functions we provide to the core */
static const OSSL_DISPATCH fips_dispatch_table[] = {
{ OSSL_FUNC_PROVIDER_GET_PARAM_TYPES, (void (*)(void))fips_get_param_types },
{ OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))fips_get_params },
{ OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fips_query },
{ 0, NULL }
};

int OSSL_provider_init(const OSSL_PROVIDER *provider,
const OSSL_DISPATCH *in,
const OSSL_DISPATCH **out)
{
for (; in->function_id != 0; in++) {
switch (in->function_id) {
case OSSL_FUNC_CORE_GET_PARAM_TYPES:
c_get_param_types = OSSL_get_core_get_param_types(in);
break;
case OSSL_FUNC_CORE_GET_PARAMS:
c_get_params = OSSL_get_core_get_params(in);
break;
/* Just ignore anything we don't understand */
default:
break;
}
}

*out = fips_dispatch_table;
return 1;
}
3 changes: 3 additions & 0 deletions test/build.info
Expand Up @@ -186,6 +186,9 @@ IF[{- !$disabled{tests} -}]
SOURCE[evp_extra_test]=evp_extra_test.c
INCLUDE[evp_extra_test]=../include ../apps/include ../crypto/include
DEPEND[evp_extra_test]=../libcrypto libtestutil.a
IF[{- $disabled{fips} || !$target{dso_scheme} -}]
DEFINE[evp_extra_test]=NO_FIPS_MODULE
ENDIF

SOURCE[igetest]=igetest.c
INCLUDE[igetest]=../include ../apps/include
Expand Down