Skip to content

Commit 7e3535c

Browse files
authored
Merge pull request libgit2#6906 from marcind-dot/add-OpenSSL-FIPS-cmake-flag
2 parents cd9f463 + 8cf4cc2 commit 7e3535c

File tree

9 files changed

+209
-11
lines changed

9 files changed

+209
-11
lines changed

.github/workflows/nightly.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,15 @@ jobs:
373373
CMAKE_OPTIONS: -A x64 -DWIN32_LEAKCHECK=ON -DDEPRECATE_HARD=ON -DEXPERIMENTAL_SHA256=ON
374374
SKIP_SSH_TESTS: true
375375
SKIP_NEGOTIATE_TESTS: true
376+
- name: "Linux (SHA256, Xenial, Clang, OpenSSL-FIPS)"
377+
id: linux-sha256-fips
378+
container:
379+
name: xenial
380+
env:
381+
CC: clang
382+
CMAKE_GENERATOR: Ninja
383+
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DUSE_SSH=ON -DUSE_SHA1=OpenSSL-FIPS -DUSE_SHA256=OpenSSL-FIPS
384+
os: ubuntu-latest
376385
fail-fast: false
377386
env: ${{ matrix.platform.env }}
378387
runs-on: ${{ matrix.platform.os }}

cmake/SelectHashes.cmake

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ if(USE_SHA1 STREQUAL "CollisionDetection")
2828
set(GIT_SHA1_COLLISIONDETECT 1)
2929
elseif(USE_SHA1 STREQUAL "OpenSSL")
3030
set(GIT_SHA1_OPENSSL 1)
31+
elseif(USE_SHA1 STREQUAL "OpenSSL-FIPS")
32+
set(GIT_SHA1_OPENSSL_FIPS 1)
3133
elseif(USE_SHA1 STREQUAL "OpenSSL-Dynamic")
3234
set(GIT_SHA1_OPENSSL 1)
3335
set(GIT_SHA1_OPENSSL_DYNAMIC 1)
@@ -66,6 +68,8 @@ if(USE_SHA256 STREQUAL "Builtin")
6668
set(GIT_SHA256_BUILTIN 1)
6769
elseif(USE_SHA256 STREQUAL "OpenSSL")
6870
set(GIT_SHA256_OPENSSL 1)
71+
elseif(USE_SHA256 STREQUAL "OpenSSL-FIPS")
72+
set(GIT_SHA256_OPENSSL_FIPS 1)
6973
elseif(USE_SHA256 STREQUAL "OpenSSL-Dynamic")
7074
set(GIT_SHA256_OPENSSL 1)
7175
set(GIT_SHA256_OPENSSL_DYNAMIC 1)
@@ -81,7 +85,8 @@ else()
8185
endif()
8286

8387
# add library requirements
84-
if(USE_SHA1 STREQUAL "OpenSSL" OR USE_SHA256 STREQUAL "OpenSSL")
88+
if(USE_SHA1 STREQUAL "OpenSSL" OR USE_SHA256 STREQUAL "OpenSSL" OR
89+
USE_SHA1 STREQUAL "OpenSSL-FIPS" OR USE_SHA256 STREQUAL "OpenSSL-FIPS")
8590
if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
8691
list(APPEND LIBGIT2_PC_LIBS "-lssl")
8792
else()

src/libgit2/commit_graph.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,9 +1027,12 @@ static int commit_graph_write_hash(const char *buf, size_t size, void *data)
10271027
struct commit_graph_write_hash_context *ctx = data;
10281028
int error;
10291029

1030-
error = git_hash_update(ctx->ctx, buf, size);
1031-
if (error < 0)
1032-
return error;
1030+
if (ctx->ctx) {
1031+
error = git_hash_update(ctx->ctx, buf, size);
1032+
1033+
if (error < 0)
1034+
return error;
1035+
}
10331036

10341037
return ctx->write_cb(buf, size, ctx->cb_data);
10351038
}
@@ -1225,6 +1228,9 @@ static int commit_graph_write(
12251228
error = git_hash_final(checksum, &ctx);
12261229
if (error < 0)
12271230
goto cleanup;
1231+
1232+
hash_cb_data.ctx = NULL;
1233+
12281234
error = write_cb((char *)checksum, checksum_size, cb_data);
12291235
if (error < 0)
12301236
goto cleanup;

src/libgit2/midx.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -660,9 +660,11 @@ static int midx_write_hash(const char *buf, size_t size, void *data)
660660
struct midx_write_hash_context *ctx = (struct midx_write_hash_context *)data;
661661
int error;
662662

663-
error = git_hash_update(ctx->ctx, buf, size);
664-
if (error < 0)
665-
return error;
663+
if (ctx->ctx) {
664+
error = git_hash_update(ctx->ctx, buf, size);
665+
if (error < 0)
666+
return error;
667+
}
666668

667669
return ctx->write_cb(buf, size, ctx->cb_data);
668670
}
@@ -863,6 +865,9 @@ static int midx_write(
863865
error = git_hash_final(checksum, &ctx);
864866
if (error < 0)
865867
goto cleanup;
868+
869+
hash_cb_data.ctx = NULL;
870+
866871
error = write_cb((char *)checksum, checksum_size, cb_data);
867872
if (error < 0)
868873
goto cleanup;

src/util/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ if(USE_SHA1 STREQUAL "CollisionDetection")
3434
target_compile_definitions(util PRIVATE SHA1DC_NO_STANDARD_INCLUDES=1)
3535
target_compile_definitions(util PRIVATE SHA1DC_CUSTOM_INCLUDE_SHA1_C=\"git2_util.h\")
3636
target_compile_definitions(util PRIVATE SHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C=\"git2_util.h\")
37-
elseif(USE_SHA1 STREQUAL "OpenSSL" OR USE_SHA1 STREQUAL "OpenSSL-Dynamic")
37+
elseif(USE_SHA1 STREQUAL "OpenSSL" OR USE_SHA1 STREQUAL "OpenSSL-Dynamic" OR USE_SHA1 STREQUAL "OpenSSL-FIPS")
3838
add_definitions(-DOPENSSL_API_COMPAT=0x10100000L)
3939
file(GLOB UTIL_SRC_SHA1 hash/openssl.*)
4040
elseif(USE_SHA1 STREQUAL "CommonCrypto")
@@ -51,7 +51,7 @@ list(SORT UTIL_SRC_SHA1)
5151

5252
if(USE_SHA256 STREQUAL "Builtin")
5353
file(GLOB UTIL_SRC_SHA256 hash/builtin.* hash/rfc6234/*)
54-
elseif(USE_SHA256 STREQUAL "OpenSSL" OR USE_SHA256 STREQUAL "OpenSSL-Dynamic")
54+
elseif(USE_SHA256 STREQUAL "OpenSSL" OR USE_SHA256 STREQUAL "OpenSSL-Dynamic" OR USE_SHA256 STREQUAL "OpenSSL-FIPS")
5555
add_definitions(-DOPENSSL_API_COMPAT=0x10100000L)
5656
file(GLOB UTIL_SRC_SHA256 hash/openssl.*)
5757
elseif(USE_SHA256 STREQUAL "CommonCrypto")

src/util/git2_features.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,15 @@
5454
#cmakedefine GIT_SHA1_WIN32 1
5555
#cmakedefine GIT_SHA1_COMMON_CRYPTO 1
5656
#cmakedefine GIT_SHA1_OPENSSL 1
57+
#cmakedefine GIT_SHA1_OPENSSL_FIPS 1
5758
#cmakedefine GIT_SHA1_OPENSSL_DYNAMIC 1
5859
#cmakedefine GIT_SHA1_MBEDTLS 1
5960

6061
#cmakedefine GIT_SHA256_BUILTIN 1
6162
#cmakedefine GIT_SHA256_WIN32 1
6263
#cmakedefine GIT_SHA256_COMMON_CRYPTO 1
6364
#cmakedefine GIT_SHA256_OPENSSL 1
65+
#cmakedefine GIT_SHA256_OPENSSL_FIPS 1
6466
#cmakedefine GIT_SHA256_OPENSSL_DYNAMIC 1
6567
#cmakedefine GIT_SHA256_MBEDTLS 1
6668

src/util/hash/openssl.c

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,82 @@ int git_hash_sha1_final(unsigned char *out, git_hash_sha1_ctx *ctx)
120120

121121
#endif
122122

123+
#ifdef GIT_SHA1_OPENSSL_FIPS
124+
125+
static const EVP_MD *SHA1_ENGINE_DIGEST_TYPE = NULL;
126+
127+
int git_hash_sha1_global_init(void)
128+
{
129+
SHA1_ENGINE_DIGEST_TYPE = EVP_sha1();
130+
return SHA1_ENGINE_DIGEST_TYPE != NULL ? 0 : -1;
131+
}
132+
133+
int git_hash_sha1_ctx_init(git_hash_sha1_ctx *ctx)
134+
{
135+
return git_hash_sha1_init(ctx);
136+
}
137+
138+
void git_hash_sha1_ctx_cleanup(git_hash_sha1_ctx *ctx)
139+
{
140+
#if OPENSSL_VERSION_NUMBER < 0x10100000L
141+
EVP_MD_CTX_destroy(ctx->c);
142+
#else
143+
EVP_MD_CTX_free(ctx->c);
144+
#endif
145+
}
146+
147+
int git_hash_sha1_init(git_hash_sha1_ctx *ctx)
148+
{
149+
GIT_ASSERT_ARG(ctx);
150+
GIT_ASSERT(SHA1_ENGINE_DIGEST_TYPE);
151+
152+
#if OPENSSL_VERSION_NUMBER < 0x10100000L
153+
ctx->c = EVP_MD_CTX_create();
154+
#else
155+
ctx->c = EVP_MD_CTX_new();
156+
#endif
157+
158+
GIT_ASSERT(ctx->c);
159+
160+
if (EVP_DigestInit_ex(ctx->c, SHA1_ENGINE_DIGEST_TYPE, NULL) != 1) {
161+
git_hash_sha1_ctx_cleanup(ctx);
162+
git_error_set(GIT_ERROR_SHA, "failed to initialize sha1 context");
163+
return -1;
164+
}
165+
166+
return 0;
167+
}
168+
169+
int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len)
170+
{
171+
GIT_ASSERT_ARG(ctx && ctx->c);
172+
173+
if (EVP_DigestUpdate(ctx->c, data, len) != 1) {
174+
git_error_set(GIT_ERROR_SHA, "failed to update sha1");
175+
return -1;
176+
}
177+
178+
return 0;
179+
}
180+
181+
int git_hash_sha1_final(unsigned char *out, git_hash_sha1_ctx *ctx)
182+
{
183+
unsigned int len = 0;
184+
185+
GIT_ASSERT_ARG(ctx && ctx->c);
186+
187+
if (EVP_DigestFinal(ctx->c, out, &len) != 1) {
188+
git_error_set(GIT_ERROR_SHA, "failed to finalize sha1");
189+
return -1;
190+
}
191+
192+
ctx->c = NULL;
193+
194+
return 0;
195+
}
196+
197+
#endif
198+
123199
#ifdef GIT_SHA256_OPENSSL
124200

125201
# ifdef GIT_OPENSSL_DYNAMIC
@@ -193,3 +269,79 @@ int git_hash_sha256_final(unsigned char *out, git_hash_sha256_ctx *ctx)
193269
}
194270

195271
#endif
272+
273+
#ifdef GIT_SHA256_OPENSSL_FIPS
274+
275+
static const EVP_MD *SHA256_ENGINE_DIGEST_TYPE = NULL;
276+
277+
int git_hash_sha256_global_init(void)
278+
{
279+
SHA256_ENGINE_DIGEST_TYPE = EVP_sha256();
280+
return SHA256_ENGINE_DIGEST_TYPE != NULL ? 0 : -1;
281+
}
282+
283+
int git_hash_sha256_ctx_init(git_hash_sha256_ctx *ctx)
284+
{
285+
return git_hash_sha256_init(ctx);
286+
}
287+
288+
void git_hash_sha256_ctx_cleanup(git_hash_sha256_ctx *ctx)
289+
{
290+
#if OPENSSL_VERSION_NUMBER < 0x10100000L
291+
EVP_MD_CTX_destroy(ctx->c);
292+
#else
293+
EVP_MD_CTX_free(ctx->c);
294+
#endif
295+
}
296+
297+
int git_hash_sha256_init(git_hash_sha256_ctx *ctx)
298+
{
299+
GIT_ASSERT_ARG(ctx);
300+
GIT_ASSERT(SHA256_ENGINE_DIGEST_TYPE);
301+
302+
#if OPENSSL_VERSION_NUMBER < 0x10100000L
303+
ctx->c = EVP_MD_CTX_create();
304+
#else
305+
ctx->c = EVP_MD_CTX_new();
306+
#endif
307+
308+
GIT_ASSERT(ctx->c);
309+
310+
if (EVP_DigestInit_ex(ctx->c, SHA256_ENGINE_DIGEST_TYPE, NULL) != 1) {
311+
git_hash_sha256_ctx_cleanup(ctx);
312+
git_error_set(GIT_ERROR_SHA, "failed to initialize sha256 context");
313+
return -1;
314+
}
315+
316+
return 0;
317+
}
318+
319+
int git_hash_sha256_update(git_hash_sha256_ctx *ctx, const void *data, size_t len)
320+
{
321+
GIT_ASSERT_ARG(ctx && ctx->c);
322+
323+
if (EVP_DigestUpdate(ctx->c, data, len) != 1) {
324+
git_error_set(GIT_ERROR_SHA, "failed to update sha256");
325+
return -1;
326+
}
327+
328+
return 0;
329+
}
330+
331+
int git_hash_sha256_final(unsigned char *out, git_hash_sha256_ctx *ctx)
332+
{
333+
unsigned int len = 0;
334+
335+
GIT_ASSERT_ARG(ctx && ctx->c);
336+
337+
if (EVP_DigestFinal(ctx->c, out, &len) != 1) {
338+
git_error_set(GIT_ERROR_SHA, "failed to finalize sha256");
339+
return -1;
340+
}
341+
342+
ctx->c = NULL;
343+
344+
return 0;
345+
}
346+
347+
#endif

src/util/hash/openssl.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111
#include "hash/sha.h"
1212

1313
#ifndef GIT_OPENSSL_DYNAMIC
14-
# include <openssl/sha.h>
14+
# if defined(GIT_SHA1_OPENSSL_FIPS) || defined(GIT_SHA256_OPENSSL_FIPS)
15+
# include <openssl/evp.h>
16+
# else
17+
# include <openssl/sha.h>
18+
# endif
1519
#else
1620

1721
typedef struct {
@@ -36,10 +40,22 @@ struct git_hash_sha1_ctx {
3640
};
3741
#endif
3842

43+
#ifdef GIT_SHA1_OPENSSL_FIPS
44+
struct git_hash_sha1_ctx {
45+
EVP_MD_CTX* c;
46+
};
47+
#endif
48+
3949
#ifdef GIT_SHA256_OPENSSL
4050
struct git_hash_sha256_ctx {
4151
SHA256_CTX c;
4252
};
4353
#endif
4454

55+
#ifdef GIT_SHA256_OPENSSL_FIPS
56+
struct git_hash_sha256_ctx {
57+
EVP_MD_CTX* c;
58+
};
59+
#endif
60+
4561
#endif

src/util/hash/sha.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ typedef struct git_hash_sha256_ctx git_hash_sha256_ctx;
1717
# include "common_crypto.h"
1818
#endif
1919

20-
#if defined(GIT_SHA1_OPENSSL) || defined(GIT_SHA256_OPENSSL)
20+
#if defined(GIT_SHA1_OPENSSL) || \
21+
defined(GIT_SHA1_OPENSSL_FIPS) || \
22+
defined(GIT_SHA256_OPENSSL) || \
23+
defined(GIT_SHA256_OPENSSL_FIPS)
2124
# include "openssl.h"
2225
#endif
2326

0 commit comments

Comments
 (0)