diff options
author | haiqing <haiqing.bai@windriver.com> | 2020-06-15 16:15:24 +0800 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2020-07-08 10:47:50 +0100 |
commit | 577f1b0b2fba641106959758cd59250ea38d0a64 (patch) | |
tree | bbe63c0c7a29f4e31d649e6fb8f9392047043732 /meta | |
parent | 4e90fb17b129b7a5df584799ec9629474362d50c (diff) | |
download | poky-577f1b0b2fba641106959758cd59250ea38d0a64.tar.gz |
gnutls: fixed CVE-2020-13777
GnuTLS 3.6.x before 3.6.14 uses incorrect cryptography
for encrypting a session ticket
Backport the patch from upstream:
https://gitlab.com/gnutls/gnutls.git
commit c2646aeee94e71cb15c90a3147cf3b5b0ca158ca
commit 50ad8778a81f9421effa4c5a3b457f98e559b178
commit 3d7fae761e65e9d0f16d7247ee8a464d4fe002da
(From OE-Core rev: 86870cd2ff3555161ea5bb434740338ec20495a0)
Signed-off-by: Haiqing Bai <Haiqing.Bai@windriver.com>
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
4 files changed, 298 insertions, 0 deletions
diff --git a/meta/recipes-support/gnutls/gnutls/CVE-2020-13777-a.patch b/meta/recipes-support/gnutls/gnutls/CVE-2020-13777-a.patch new file mode 100644 index 0000000000..1811afc2ff --- /dev/null +++ b/meta/recipes-support/gnutls/gnutls/CVE-2020-13777-a.patch | |||
@@ -0,0 +1,90 @@ | |||
1 | From 6e798091d057de6b7f94b9dede4c5c919ec41f89 Mon Sep 17 00:00:00 2001 | ||
2 | From: Daiki Ueno <ueno@gnu.org> | ||
3 | Date: Tue, 2 Jun 2020 20:53:11 +0200 | ||
4 | Subject: [PATCH 1/3] stek: differentiate initial state from valid time window | ||
5 | of TOTP | ||
6 | |||
7 | commit c2646aeee94e71cb15c90a3147cf3b5b0ca158ca from https://gitlab.com/gnutls/gnutls.git | ||
8 | |||
9 | There was a confusion in the TOTP implementation in stek.c. When the | ||
10 | mechanism is initialized at the first time, it records the timestamp | ||
11 | but doesn't initialize the key. This removes the timestamp recording | ||
12 | at the initialization phase, so the key is properly set later. | ||
13 | |||
14 | Upstream-Status: Backport | ||
15 | |||
16 | Signed-off-by: Daiki Ueno <ueno@gnu.org> | ||
17 | Signed-off-by: Haiqing Bai <Haiqing.Bai@windriver.com> | ||
18 | --- | ||
19 | lib/stek.c | 17 +++++------------ | ||
20 | tests/resume-with-previous-stek.c | 4 ++-- | ||
21 | tests/tls13/prf-early.c | 8 ++++---- | ||
22 | 3 files changed, 11 insertions(+), 18 deletions(-) | ||
23 | |||
24 | diff --git a/lib/stek.c b/lib/stek.c | ||
25 | index 2f885ce..5ab9e7d 100644 | ||
26 | --- a/lib/stek.c | ||
27 | +++ b/lib/stek.c | ||
28 | @@ -323,20 +323,13 @@ int _gnutls_initialize_session_ticket_key_rotation(gnutls_session_t session, con | ||
29 | if (unlikely(session == NULL || key == NULL)) | ||
30 | return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); | ||
31 | |||
32 | - if (session->key.totp.last_result == 0) { | ||
33 | - int64_t t; | ||
34 | - memcpy(session->key.initial_stek, key->data, key->size); | ||
35 | - t = totp_next(session); | ||
36 | - if (t < 0) | ||
37 | - return gnutls_assert_val(t); | ||
38 | + if (unlikely(session->key.totp.last_result != 0)) | ||
39 | + return GNUTLS_E_INVALID_REQUEST; | ||
40 | |||
41 | - session->key.totp.last_result = t; | ||
42 | - session->key.totp.was_rotated = 0; | ||
43 | - | ||
44 | - return GNUTLS_E_SUCCESS; | ||
45 | - } | ||
46 | + memcpy(session->key.initial_stek, key->data, key->size); | ||
47 | |||
48 | - return GNUTLS_E_INVALID_REQUEST; | ||
49 | + session->key.totp.was_rotated = 0; | ||
50 | + return 0; | ||
51 | } | ||
52 | |||
53 | /* | ||
54 | diff --git a/tests/resume-with-previous-stek.c b/tests/resume-with-previous-stek.c | ||
55 | index f212b18..05c1c90 100644 | ||
56 | --- a/tests/resume-with-previous-stek.c | ||
57 | +++ b/tests/resume-with-previous-stek.c | ||
58 | @@ -196,8 +196,8 @@ static void server(int fd, unsigned rounds, const char *prio) | ||
59 | serverx509cred = NULL; | ||
60 | } | ||
61 | |||
62 | - if (num_stek_rotations != 2) | ||
63 | - fail("STEK should be rotated exactly twice (%d)!\n", num_stek_rotations); | ||
64 | + if (num_stek_rotations != 3) | ||
65 | + fail("STEK should be rotated exactly three times (%d)!\n", num_stek_rotations); | ||
66 | |||
67 | if (serverx509cred) | ||
68 | gnutls_certificate_free_credentials(serverx509cred); | ||
69 | diff --git a/tests/tls13/prf-early.c b/tests/tls13/prf-early.c | ||
70 | index 414b1db..bc31962 100644 | ||
71 | --- a/tests/tls13/prf-early.c | ||
72 | +++ b/tests/tls13/prf-early.c | ||
73 | @@ -123,10 +123,10 @@ static void dump(const char *name, const uint8_t *data, unsigned data_size) | ||
74 | } \ | ||
75 | } | ||
76 | |||
77 | -#define KEY_EXP_VALUE "\xc0\x1e\xc2\xa4\xb7\xb4\x04\xaa\x91\x5d\xaf\xe8\xf7\x4d\x19\xdf\xd0\xe6\x08\xd6\xb4\x3b\xcf\xca\xc9\x32\x75\x3b\xe3\x11\x19\xb1\xac\x68" | ||
78 | -#define HELLO_VALUE "\x77\xdb\x10\x0b\xe8\xd0\xb9\x38\xbc\x49\xe6\xbe\xf2\x47\x2a\xcc\x6b\xea\xce\x85\x04\xd3\x9e\xd8\x06\x16\xad\xff\xcd\xbf\x4b" | ||
79 | -#define CONTEXT_VALUE "\xf2\x17\x9f\xf2\x66\x56\x87\x66\xf9\x5c\x8a\xd7\x4e\x1d\x46\xee\x0e\x44\x41\x4c\xcd\xac\xcb\xc0\x31\x41\x2a\xb6\xd7\x01\x62" | ||
80 | -#define NULL_CONTEXT_VALUE "\xcd\x79\x07\x93\xeb\x96\x07\x3e\xec\x78\x90\x89\xf7\x16\x42\x6d\x27\x87\x56\x7c\x7b\x60\x2b\x20\x44\xd1\xea\x0c\x89\xfb\x8b" | ||
81 | +#define KEY_EXP_VALUE "\xc1\x6b\x6c\xb9\x88\x33\xd5\x28\x80\xec\x27\x87\xa2\x6f\x4b\xd0\x01\x5e\x7f\xca\xd7\xd4\x8a\x3f\xe2\x48\x92\xef\x02\x14\xfb\x81\x90\x04" | ||
82 | +#define HELLO_VALUE "\x2a\x73\xd9\x74\x04\x4e\x0a\x5f\x41\x8a\x09\xcb\x45\x33\x1a\xec\xd3\xfc\xdc\x1b\x2c\x67\x26\xe4\x9c\xfe\x1f\xa5\x74\xf1\x4f" | ||
83 | +#define CONTEXT_VALUE "\x87\xf6\x88\xe3\xd7\xf2\x05\xbc\xa4\x10\xa3\x48\x9f\xf5\xcf\x97\x06\x22\x4e\xfd\x18\x32\x52\x1d\xbd\x26\xf5\x5b\x21\x20\xec" | ||
84 | +#define NULL_CONTEXT_VALUE "\xf9\xca\xfe\x45\x44\x96\xdb\xc5\x41\x8f\x7e\x8e\xd7\xb0\x7d\x19\x45\xaf\x09\xbc\x1e\x82\x94\xac\x55\xe5\xb9\xb4\x3b\xe8\xc0" | ||
85 | |||
86 | static int handshake_callback_called; | ||
87 | |||
88 | -- | ||
89 | 2.17.1 | ||
90 | |||
diff --git a/meta/recipes-support/gnutls/gnutls/CVE-2020-13777-b.patch b/meta/recipes-support/gnutls/gnutls/CVE-2020-13777-b.patch new file mode 100644 index 0000000000..12486e1710 --- /dev/null +++ b/meta/recipes-support/gnutls/gnutls/CVE-2020-13777-b.patch | |||
@@ -0,0 +1,137 @@ | |||
1 | From 6c7f9703e42bc5278d0a4a6f0a39d07d62123ea3 Mon Sep 17 00:00:00 2001 | ||
2 | From: Daiki Ueno <dueno@redhat.com> | ||
3 | Date: Tue, 31 Mar 2020 06:58:48 +0200 | ||
4 | Subject: [PATCH 2/3] build: use valgrind client request to detect undefined | ||
5 | memory use | ||
6 | |||
7 | commit 50ad8778a81f9421effa4c5a3b457f98e559b178 from https://gitlab.com/gnutls/gnutls.git | ||
8 | |||
9 | This tightens the check introduced in | ||
10 | ac2f71b892d13a7ab4cc39086eef179042c7e23c, by using the valgrind client | ||
11 | request to explicitly mark the "uninitialized but initialization is | ||
12 | needed before use" regions. With this patch and the | ||
13 | fix (c01011c2d8533dbbbe754e49e256c109cb848d0d) reverted, you will see | ||
14 | the following error when running dtls_hello_random_value under | ||
15 | valgrind: | ||
16 | |||
17 | $ valgrind ./dtls_hello_random_value | ||
18 | testing: default | ||
19 | ==520145== Conditional jump or move depends on uninitialised value(s) | ||
20 | ==520145== at 0x4025F5: hello_callback (dtls_hello_random_value.c:90) | ||
21 | ==520145== by 0x488BF97: _gnutls_call_hook_func (handshake.c:1215) | ||
22 | ==520145== by 0x488C1AA: _gnutls_send_handshake2 (handshake.c:1332) | ||
23 | ==520145== by 0x488FC7E: send_client_hello (handshake.c:2290) | ||
24 | ==520145== by 0x48902A1: handshake_client (handshake.c:2908) | ||
25 | ==520145== by 0x48902A1: gnutls_handshake (handshake.c:2740) | ||
26 | ==520145== by 0x402CB3: client (dtls_hello_random_value.c:153) | ||
27 | ==520145== by 0x402CB3: start (dtls_hello_random_value.c:317) | ||
28 | ==520145== by 0x402EFE: doit (dtls_hello_random_value.c:331) | ||
29 | ==520145== by 0x4023D4: main (utils.c:254) | ||
30 | ==520145== | ||
31 | |||
32 | Upstream-Status: Backport | ||
33 | |||
34 | Signed-off-by: Daiki Ueno <dueno@redhat.com> | ||
35 | Signed-off-by: Haiqing Bai <Haiqing.Bai@windriver.com> | ||
36 | --- | ||
37 | configure.ac | 2 ++ | ||
38 | lib/handshake.c | 15 +++++++++++++++ | ||
39 | lib/state.c | 21 ++++++++++++++++++--- | ||
40 | 3 files changed, 35 insertions(+), 3 deletions(-) | ||
41 | |||
42 | diff --git a/configure.ac b/configure.ac | ||
43 | index 172cf42..12da283 100644 | ||
44 | --- a/configure.ac | ||
45 | +++ b/configure.ac | ||
46 | @@ -233,6 +233,8 @@ AS_IF([test "$ac_cv_search___atomic_load_4" = "none required" || test "$ac_cv_se | ||
47 | dnl We use its presence to detect C11 threads | ||
48 | AC_CHECK_HEADERS([threads.h]) | ||
49 | |||
50 | +AC_CHECK_HEADERS([valgrind/memcheck.h]) | ||
51 | + | ||
52 | AC_ARG_ENABLE(padlock, | ||
53 | AS_HELP_STRING([--disable-padlock], [unconditionally disable padlock acceleration]), | ||
54 | use_padlock=$enableval) | ||
55 | diff --git a/lib/handshake.c b/lib/handshake.c | ||
56 | index 84a0e52..8d58fa4 100644 | ||
57 | --- a/lib/handshake.c | ||
58 | +++ b/lib/handshake.c | ||
59 | @@ -57,6 +57,9 @@ | ||
60 | #include "secrets.h" | ||
61 | #include "tls13/session_ticket.h" | ||
62 | #include "locks.h" | ||
63 | +#ifdef HAVE_VALGRIND_MEMCHECK_H | ||
64 | +#include <valgrind/memcheck.h> | ||
65 | +#endif | ||
66 | |||
67 | #define TRUE 1 | ||
68 | #define FALSE 0 | ||
69 | @@ -242,6 +245,12 @@ int _gnutls_gen_client_random(gnutls_session_t session) | ||
70 | return gnutls_assert_val(ret); | ||
71 | } | ||
72 | |||
73 | +#ifdef HAVE_VALGRIND_MEMCHECK_H | ||
74 | + if (RUNNING_ON_VALGRIND) | ||
75 | + VALGRIND_MAKE_MEM_DEFINED(session->security_parameters.client_random, | ||
76 | + GNUTLS_RANDOM_SIZE); | ||
77 | +#endif | ||
78 | + | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | @@ -320,6 +329,12 @@ int _gnutls_gen_server_random(gnutls_session_t session, int version) | ||
83 | return ret; | ||
84 | } | ||
85 | |||
86 | +#ifdef HAVE_VALGRIND_MEMCHECK_H | ||
87 | + if (RUNNING_ON_VALGRIND) | ||
88 | + VALGRIND_MAKE_MEM_DEFINED(session->security_parameters.server_random, | ||
89 | + GNUTLS_RANDOM_SIZE); | ||
90 | +#endif | ||
91 | + | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | diff --git a/lib/state.c b/lib/state.c | ||
96 | index 0e1d155..98900c1 100644 | ||
97 | --- a/lib/state.c | ||
98 | +++ b/lib/state.c | ||
99 | @@ -55,6 +55,9 @@ | ||
100 | #include "ext/cert_types.h" | ||
101 | #include "locks.h" | ||
102 | #include "kx.h" | ||
103 | +#ifdef HAVE_VALGRIND_MEMCHECK_H | ||
104 | +#include <valgrind/memcheck.h> | ||
105 | +#endif | ||
106 | |||
107 | /* to be used by supplemental data support to disable TLS1.3 | ||
108 | * when supplemental data have been globally registered */ | ||
109 | @@ -564,10 +567,22 @@ int gnutls_init(gnutls_session_t * session, unsigned int flags) | ||
110 | UINT32_MAX; | ||
111 | } | ||
112 | |||
113 | - /* everything else not initialized here is initialized | ||
114 | - * as NULL or 0. This is why calloc is used. | ||
115 | + /* Everything else not initialized here is initialized as NULL | ||
116 | + * or 0. This is why calloc is used. However, we want to | ||
117 | + * ensure that certain portions of data are initialized at | ||
118 | + * runtime before being used. Mark such regions with a | ||
119 | + * valgrind client request as undefined. | ||
120 | */ | ||
121 | - | ||
122 | +#ifdef HAVE_VALGRIND_MEMCHECK_H | ||
123 | + if (RUNNING_ON_VALGRIND) { | ||
124 | + if (flags & GNUTLS_CLIENT) | ||
125 | + VALGRIND_MAKE_MEM_UNDEFINED((*session)->security_parameters.client_random, | ||
126 | + GNUTLS_RANDOM_SIZE); | ||
127 | + if (flags & GNUTLS_SERVER) | ||
128 | + VALGRIND_MAKE_MEM_UNDEFINED((*session)->security_parameters.server_random, | ||
129 | + GNUTLS_RANDOM_SIZE); | ||
130 | + } | ||
131 | +#endif | ||
132 | handshake_internal_state_clear1(*session); | ||
133 | |||
134 | #ifdef HAVE_WRITEV | ||
135 | -- | ||
136 | 2.17.1 | ||
137 | |||
diff --git a/meta/recipes-support/gnutls/gnutls/CVE-2020-13777-c.patch b/meta/recipes-support/gnutls/gnutls/CVE-2020-13777-c.patch new file mode 100644 index 0000000000..2d8efeb889 --- /dev/null +++ b/meta/recipes-support/gnutls/gnutls/CVE-2020-13777-c.patch | |||
@@ -0,0 +1,68 @@ | |||
1 | From b34da057dc9eb01df30b436ba9cb047c21fb0151 Mon Sep 17 00:00:00 2001 | ||
2 | From: Daiki Ueno <ueno@gnu.org> | ||
3 | Date: Tue, 2 Jun 2020 21:45:17 +0200 | ||
4 | Subject: [PATCH 3/3] valgrind: check if session ticket key is used without | ||
5 | initialization | ||
6 | |||
7 | commit 3d7fae761e65e9d0f16d7247ee8a464d4fe002da from https://gitlab.com/gnutls/gnutls.git | ||
8 | |||
9 | This adds a valgrind client request for | ||
10 | session->key.session_ticket_key to make sure that it is not used | ||
11 | without initialization. | ||
12 | |||
13 | Upstream-Status: Backport | ||
14 | |||
15 | Signed-off-by: Daiki Ueno <ueno@gnu.org> | ||
16 | Signed-off-by: Haiqing Bai <Haiqing.Bai@windriver.com> | ||
17 | --- | ||
18 | lib/state.c | 5 ++++- | ||
19 | lib/stek.c | 8 ++++++++ | ||
20 | 2 files changed, 12 insertions(+), 1 deletion(-) | ||
21 | |||
22 | diff --git a/lib/state.c b/lib/state.c | ||
23 | index 98900c1..cabdf7d 100644 | ||
24 | --- a/lib/state.c | ||
25 | +++ b/lib/state.c | ||
26 | @@ -578,9 +578,12 @@ int gnutls_init(gnutls_session_t * session, unsigned int flags) | ||
27 | if (flags & GNUTLS_CLIENT) | ||
28 | VALGRIND_MAKE_MEM_UNDEFINED((*session)->security_parameters.client_random, | ||
29 | GNUTLS_RANDOM_SIZE); | ||
30 | - if (flags & GNUTLS_SERVER) | ||
31 | + if (flags & GNUTLS_SERVER) { | ||
32 | VALGRIND_MAKE_MEM_UNDEFINED((*session)->security_parameters.server_random, | ||
33 | GNUTLS_RANDOM_SIZE); | ||
34 | + VALGRIND_MAKE_MEM_UNDEFINED((*session)->key.session_ticket_key, | ||
35 | + TICKET_MASTER_KEY_SIZE); | ||
36 | + } | ||
37 | } | ||
38 | #endif | ||
39 | handshake_internal_state_clear1(*session); | ||
40 | diff --git a/lib/stek.c b/lib/stek.c | ||
41 | index 5ab9e7d..316555b 100644 | ||
42 | --- a/lib/stek.c | ||
43 | +++ b/lib/stek.c | ||
44 | @@ -21,6 +21,9 @@ | ||
45 | */ | ||
46 | #include "gnutls_int.h" | ||
47 | #include "stek.h" | ||
48 | +#ifdef HAVE_VALGRIND_MEMCHECK_H | ||
49 | +#include <valgrind/memcheck.h> | ||
50 | +#endif | ||
51 | |||
52 | #define NAME_POS (0) | ||
53 | #define KEY_POS (TICKET_KEY_NAME_SIZE) | ||
54 | @@ -143,6 +146,11 @@ static int rotate(gnutls_session_t session) | ||
55 | call_rotation_callback(session, key, t); | ||
56 | session->key.totp.last_result = t; | ||
57 | memcpy(session->key.session_ticket_key, key, sizeof(key)); | ||
58 | +#ifdef HAVE_VALGRIND_MEMCHECK_H | ||
59 | + if (RUNNING_ON_VALGRIND) | ||
60 | + VALGRIND_MAKE_MEM_DEFINED(session->key.session_ticket_key, | ||
61 | + TICKET_MASTER_KEY_SIZE); | ||
62 | +#endif | ||
63 | |||
64 | session->key.totp.was_rotated = 1; | ||
65 | } else if (t < 0) { | ||
66 | -- | ||
67 | 2.17.1 | ||
68 | |||
diff --git a/meta/recipes-support/gnutls/gnutls_3.6.13.bb b/meta/recipes-support/gnutls/gnutls_3.6.13.bb index f56d42a613..ab537981ac 100644 --- a/meta/recipes-support/gnutls/gnutls_3.6.13.bb +++ b/meta/recipes-support/gnutls/gnutls_3.6.13.bb | |||
@@ -19,6 +19,9 @@ SHRT_VER = "${@d.getVar('PV').split('.')[0]}.${@d.getVar('PV').split('.')[1]}" | |||
19 | 19 | ||
20 | SRC_URI = "https://www.gnupg.org/ftp/gcrypt/gnutls/v${SHRT_VER}/gnutls-${PV}.tar.xz \ | 20 | SRC_URI = "https://www.gnupg.org/ftp/gcrypt/gnutls/v${SHRT_VER}/gnutls-${PV}.tar.xz \ |
21 | file://arm_eabi.patch \ | 21 | file://arm_eabi.patch \ |
22 | file://CVE-2020-13777-a.patch \ | ||
23 | file://CVE-2020-13777-b.patch \ | ||
24 | file://CVE-2020-13777-c.patch \ | ||
22 | " | 25 | " |
23 | 26 | ||
24 | SRC_URI[md5sum] = "bb1fe696a11543433785b4fc70ca225f" | 27 | SRC_URI[md5sum] = "bb1fe696a11543433785b4fc70ca225f" |