Skip to content

Commit 3348570

Browse files
authored
Merge pull request libgit2#4136 from libgit2/ethomson/sha1dc
Introduce (optional) SHA1 collision attack detection
2 parents ba2bc49 + 9f128d2 commit 3348570

File tree

12 files changed

+1815
-9
lines changed

12 files changed

+1815
-9
lines changed

CMakeLists.txt

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ OPTION( PROFILE "Generate profiling information" OFF )
3737
OPTION( ENABLE_TRACE "Enables tracing support" OFF )
3838
OPTION( LIBGIT2_FILENAME "Name of the produced binary" OFF )
3939

40+
OPTION( USE_SHA1DC "Use SHA-1 with collision detection" OFF )
4041
OPTION( USE_ICONV "Link with and use iconv library" OFF )
4142
OPTION( USE_SSH "Link with libssh to enable SSH support" ON )
4243
OPTION( USE_GSSAPI "Link with libgssapi for SPNEGO auth" OFF )
@@ -292,13 +293,16 @@ ELSE ()
292293
ENDIF()
293294

294295
# Specify sha1 implementation
295-
IF (WIN32 AND NOT MINGW AND NOT SHA1_TYPE STREQUAL "builtin")
296-
ADD_DEFINITIONS(-DWIN32_SHA1)
296+
IF (USE_SHA1DC)
297+
ADD_DEFINITIONS(-DGIT_SHA1_COLLISIONDETECT)
298+
FILE(GLOB SRC_SHA1 src/hash/hash_collisiondetect.c src/hash/sha1dc/*)
299+
ELSEIF (WIN32 AND NOT MINGW)
300+
ADD_DEFINITIONS(-DGIT_SHA1_WIN32)
297301
FILE(GLOB SRC_SHA1 src/hash/hash_win32.c)
298302
ELSEIF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
299-
ADD_DEFINITIONS(-DGIT_COMMON_CRYPTO)
300-
ELSEIF (OPENSSL_FOUND AND NOT SHA1_TYPE STREQUAL "builtin")
301-
ADD_DEFINITIONS(-DOPENSSL_SHA1)
303+
ADD_DEFINITIONS(-DGIT_SHA1_COMMON_CRYPTO)
304+
ELSEIF (OPENSSL_FOUND)
305+
ADD_DEFINITIONS(-DGIT_SHA1_OPENSSL)
302306
IF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
303307
LIST(APPEND LIBGIT2_PC_LIBS "-lssl")
304308
ELSE()

COPYING

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,3 +958,36 @@ necessary. Here is a sample; alter the names:
958958
That's all there is to it!
959959

960960
----------------------------------------------------------------------
961+
962+
The bundled SHA1 collision detection code is licensed under the MIT license:
963+
964+
MIT License
965+
966+
Copyright (c) 2017:
967+
Marc Stevens
968+
Cryptology Group
969+
Centrum Wiskunde & Informatica
970+
P.O. Box 94079, 1090 GB Amsterdam, Netherlands
971+
marc@marc-stevens.nl
972+
973+
Dan Shumow
974+
Microsoft Research
975+
danshu@microsoft.com
976+
977+
Permission is hereby granted, free of charge, to any person obtaining a copy
978+
of this software and associated documentation files (the "Software"), to deal
979+
in the Software without restriction, including without limitation the rights
980+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
981+
copies of the Software, and to permit persons to whom the Software is
982+
furnished to do so, subject to the following conditions:
983+
984+
The above copyright notice and this permission notice shall be included in all
985+
copies or substantial portions of the Software.
986+
987+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
988+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
989+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
990+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
991+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
992+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
993+
SOFTWARE.

include/git2/errors.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ typedef enum {
100100
GITERR_REBASE,
101101
GITERR_FILESYSTEM,
102102
GITERR_PATCH,
103-
GITERR_WORKTREE
103+
GITERR_WORKTREE,
104+
GITERR_SHA1
104105
} git_error_t;
105106

106107
/**

src/hash.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ int git_hash_global_init(void);
1616
int git_hash_ctx_init(git_hash_ctx *ctx);
1717
void git_hash_ctx_cleanup(git_hash_ctx *ctx);
1818

19-
#if defined(GIT_COMMON_CRYPTO)
19+
#if defined(GIT_SHA1_COLLISIONDETECT)
20+
# include "hash/hash_collisiondetect.h"
21+
#elif defined(GIT_SHA1_COMMON_CRYPTO)
2022
# include "hash/hash_common_crypto.h"
21-
#elif defined(OPENSSL_SHA1)
23+
#elif defined(GIT_SHA1_OPENSSL)
2224
# include "hash/hash_openssl.h"
23-
#elif defined(WIN32_SHA1)
25+
#elif defined(GIT_SHA1_WIN32)
2426
# include "hash/hash_win32.h"
2527
#else
2628
# include "hash/hash_generic.h"

src/hash/hash_collisiondetect.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (C) the libgit2 contributors. All rights reserved.
3+
*
4+
* This file is part of libgit2, distributed under the GNU GPL v2 with
5+
* a Linking Exception. For full terms see the included COPYING file.
6+
*/
7+
8+
#ifndef INCLUDE_hash_collisiondetect_h__
9+
#define INCLUDE_hash_collisiondetect_h__
10+
11+
#include "hash.h"
12+
#include "sha1dc/sha1.h"
13+
14+
struct git_hash_ctx {
15+
SHA1_CTX c;
16+
};
17+
18+
#define git_hash_global_init() 0
19+
#define git_hash_ctx_init(ctx) git_hash_init(ctx)
20+
#define git_hash_ctx_cleanup(ctx)
21+
22+
GIT_INLINE(int) git_hash_init(git_hash_ctx *ctx)
23+
{
24+
assert(ctx);
25+
SHA1DCInit(&ctx->c);
26+
return 0;
27+
}
28+
29+
GIT_INLINE(int) git_hash_update(git_hash_ctx *ctx, const void *data, size_t len)
30+
{
31+
const char *p = data;
32+
33+
assert(ctx);
34+
35+
/* We expect a size_t, but sha1dc only takes an int */
36+
while (len > INT_MAX) {
37+
SHA1DCUpdate(&ctx->c, p, INT_MAX);
38+
p += INT_MAX;
39+
len -= INT_MAX;
40+
}
41+
42+
SHA1DCUpdate(&ctx->c, p, len);
43+
return 0;
44+
}
45+
46+
GIT_INLINE(int) git_hash_final(git_oid *out, git_hash_ctx *ctx)
47+
{
48+
assert(ctx);
49+
if (SHA1DCFinal(out->id, &ctx->c)) {
50+
giterr_set(GITERR_SHA1, "SHA1 collision attack detected");
51+
return -1;
52+
}
53+
54+
return 0;
55+
}
56+
57+
#endif /* INCLUDE_hash_collisiondetect_h__ */

0 commit comments

Comments
 (0)