summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMeenali Gupta <meenali.gupta@windriver.com>2024-04-16 11:05:35 +0000
committerSteve Sakoman <steve@sakoman.com>2024-04-21 06:33:34 -0700
commit888ea24812c21910e74c864313be56f02fad6c2e (patch)
treeb9ad92d83c04a557720dcbf5e603c03d044cded1
parent364c5c906e20e8c3a5dc93309281b52ed92dc351 (diff)
downloadpoky-888ea24812c21910e74c864313be56f02fad6c2e.tar.gz
libssh2: fix CVE-2023-48795
References: https://nvd.nist.gov/vuln/detail/CVE-2023-48795 (From OE-Core rev: a4a727839e608d114becc709c511651b4f546c6f) Signed-off-by: Meenali Gupta <meenali.gupta@windriver.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r--meta/recipes-support/libssh2/libssh2/CVE-2023-48795.patch459
-rw-r--r--meta/recipes-support/libssh2/libssh2_1.10.0.bb1
2 files changed, 460 insertions, 0 deletions
diff --git a/meta/recipes-support/libssh2/libssh2/CVE-2023-48795.patch b/meta/recipes-support/libssh2/libssh2/CVE-2023-48795.patch
new file mode 100644
index 0000000000..c7a228217f
--- /dev/null
+++ b/meta/recipes-support/libssh2/libssh2/CVE-2023-48795.patch
@@ -0,0 +1,459 @@
1From d34d9258b8420b19ec3f97b4cc5bf7aa7d98e35a Mon Sep 17 00:00:00 2001
2From: Michael Buckley <michael@buckleyisms.com>
3Date: Thu, 30 Nov 2023 15:08:02 -0800
4Subject: [PATCH] src: add 'strict KEX' to fix CVE-2023-48795 "Terrapin Attack"
5
6Refs:
7https://terrapin-attack.com/ https://seclists.org/oss-sec/2023/q4/292
8https://osv.dev/list?ecosystem=&q=CVE-2023-48795 GHSA-45x7-px36-x8w8
9https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-48795
10
11Fixes #1290
12Closes #1291
13
14CVE: CVE-2023-48795
15Upstream-Status: Backport [https://github.com/libssh2/libssh2/commit/d34d9258b8420b19ec3f97b4cc5bf7aa7d98e35a]
16
17Signed-off-by: Meenali Gupta <meenali.gupta@windriver.com>
18---
19 src/kex.c | 64 +++++++++++++++++++++-------------
20 src/libssh2_priv.h | 18 +++++++---
21 src/packet.c | 85 +++++++++++++++++++++++++++++++++++++++++++---
22 src/packet.h | 2 +-
23 src/session.c | 3 ++
24 src/transport.c | 12 ++++++-
25 6 files changed, 150 insertions(+), 34 deletions(-)
26
27diff --git a/src/kex.c b/src/kex.c
28index 9f3ef79..e040dcd 100644
29--- a/src/kex.c
30+++ b/src/kex.c
31@@ -3026,6 +3026,13 @@ kex_method_ssh_curve25519_sha256 = {
32 };
33 #endif
34
35+static const LIBSSH2_KEX_METHOD
36+kex_method_strict_client_extension = {
37+ "kex-strict-c-v00@openssh.com",
38+ NULL,
39+ 0,
40+};
41+
42 static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = {
43 #if LIBSSH2_ED25519
44 &kex_method_ssh_curve25519_sha256,
45@@ -3043,6 +3050,7 @@ static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = {
46 &kex_method_diffie_helman_group14_sha1,
47 &kex_method_diffie_helman_group1_sha1,
48 &kex_method_diffie_helman_group_exchange_sha1,
49+ &kex_method_strict_client_extension,
50 NULL
51 };
52
53@@ -3281,13 +3289,13 @@ static int kexinit(LIBSSH2_SESSION * session)
54 return 0;
55 }
56
57-/* kex_agree_instr
58+/* _libssh2_kex_agree_instr
59 * Kex specific variant of strstr()
60 * Needle must be precede by BOL or ',', and followed by ',' or EOL
61 */
62-static unsigned char *
63-kex_agree_instr(unsigned char *haystack, unsigned long haystack_len,
64- const unsigned char *needle, unsigned long needle_len)
65+unsigned char *
66+_libssh2_kex_agree_instr(unsigned char *haystack, size_t haystack_len,
67+ const unsigned char *needle, size_t needle_len)
68 {
69 unsigned char *s;
70 unsigned char *end_haystack;
71@@ -3371,7 +3379,7 @@ static int kex_agree_hostkey(LIBSSH2_SESSION * session,
72 while(s && *s) {
73 unsigned char *p = (unsigned char *) strchr((char *) s, ',');
74 size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
75- if(kex_agree_instr(hostkey, hostkey_len, s, method_len)) {
76+ if(_libssh2_kex_agree_instr(hostkey, hostkey_len, s, method_len)) {
77 const LIBSSH2_HOSTKEY_METHOD *method =
78 (const LIBSSH2_HOSTKEY_METHOD *)
79 kex_get_method_by_name((char *) s, method_len,
80@@ -3405,9 +3413,9 @@ static int kex_agree_hostkey(LIBSSH2_SESSION * session,
81 }
82
83 while(hostkeyp && (*hostkeyp) && (*hostkeyp)->name) {
84- s = kex_agree_instr(hostkey, hostkey_len,
85- (unsigned char *) (*hostkeyp)->name,
86- strlen((*hostkeyp)->name));
87+ s = _libssh2_kex_agree_instr(hostkey, hostkey_len,
88+ (unsigned char *) (*hostkeyp)->name,
89+ strlen((*hostkeyp)->name));
90 if(s) {
91 /* So far so good, but does it suit our purposes? (Encrypting vs
92 Signing) */
93@@ -3442,13 +3450,19 @@ static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex,
94 const LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods;
95 unsigned char *s;
96
97+ const unsigned char *strict =
98+ (unsigned char *)"kex-strict-s-v00@openssh.com";
99+
100+ if(_libssh2_kex_agree_instr(kex, kex_len, strict, 28)) {
101+ session->kex_strict = 1;
102+ }
103 if(session->kex_prefs) {
104 s = (unsigned char *) session->kex_prefs;
105
106 while(s && *s) {
107 unsigned char *q, *p = (unsigned char *) strchr((char *) s, ',');
108 size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
109- q = kex_agree_instr(kex, kex_len, s, method_len);
110+ q = _libssh2_kex_agree_instr(kex, kex_len, s, method_len);
111 if(q) {
112 const LIBSSH2_KEX_METHOD *method = (const LIBSSH2_KEX_METHOD *)
113 kex_get_method_by_name((char *) s, method_len,
114@@ -3482,9 +3496,9 @@ static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex,
115 }
116
117 while(*kexp && (*kexp)->name) {
118- s = kex_agree_instr(kex, kex_len,
119- (unsigned char *) (*kexp)->name,
120- strlen((*kexp)->name));
121+ s = _libssh2_kex_agree_instr(kex, kex_len,
122+ (unsigned char *) (*kexp)->name,
123+ strlen((*kexp)->name));
124 if(s) {
125 /* We've agreed on a key exchange method,
126 * Can we agree on a hostkey that works with this kex?
127@@ -3528,7 +3542,7 @@ static int kex_agree_crypt(LIBSSH2_SESSION * session,
128 unsigned char *p = (unsigned char *) strchr((char *) s, ',');
129 size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
130
131- if(kex_agree_instr(crypt, crypt_len, s, method_len)) {
132+ if(_libssh2_kex_agree_instr(crypt, crypt_len, s, method_len)) {
133 const LIBSSH2_CRYPT_METHOD *method =
134 (const LIBSSH2_CRYPT_METHOD *)
135 kex_get_method_by_name((char *) s, method_len,
136@@ -3550,9 +3564,9 @@ static int kex_agree_crypt(LIBSSH2_SESSION * session,
137 }
138
139 while(*cryptp && (*cryptp)->name) {
140- s = kex_agree_instr(crypt, crypt_len,
141- (unsigned char *) (*cryptp)->name,
142- strlen((*cryptp)->name));
143+ s = _libssh2_kex_agree_instr(crypt, crypt_len,
144+ (unsigned char *) (*cryptp)->name,
145+ strlen((*cryptp)->name));
146 if(s) {
147 endpoint->crypt = *cryptp;
148 return 0;
149@@ -3583,7 +3597,7 @@ static int kex_agree_mac(LIBSSH2_SESSION * session,
150 unsigned char *p = (unsigned char *) strchr((char *) s, ',');
151 size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
152
153- if(kex_agree_instr(mac, mac_len, s, method_len)) {
154+ if(_libssh2_kex_agree_instr(mac, mac_len, s, method_len)) {
155 const LIBSSH2_MAC_METHOD *method = (const LIBSSH2_MAC_METHOD *)
156 kex_get_method_by_name((char *) s, method_len,
157 (const LIBSSH2_COMMON_METHOD **)
158@@ -3604,8 +3618,9 @@ static int kex_agree_mac(LIBSSH2_SESSION * session,
159 }
160
161 while(*macp && (*macp)->name) {
162- s = kex_agree_instr(mac, mac_len, (unsigned char *) (*macp)->name,
163- strlen((*macp)->name));
164+ s = _libssh2_kex_agree_instr(mac, mac_len,
165+ (unsigned char *) (*macp)->name,
166+ strlen((*macp)->name));
167 if(s) {
168 endpoint->mac = *macp;
169 return 0;
170@@ -3636,7 +3651,7 @@ static int kex_agree_comp(LIBSSH2_SESSION *session,
171 unsigned char *p = (unsigned char *) strchr((char *) s, ',');
172 size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
173
174- if(kex_agree_instr(comp, comp_len, s, method_len)) {
175+ if(_libssh2_kex_agree_instr(comp, comp_len, s, method_len)) {
176 const LIBSSH2_COMP_METHOD *method =
177 (const LIBSSH2_COMP_METHOD *)
178 kex_get_method_by_name((char *) s, method_len,
179@@ -3658,8 +3673,9 @@ static int kex_agree_comp(LIBSSH2_SESSION *session,
180 }
181
182 while(*compp && (*compp)->name) {
183- s = kex_agree_instr(comp, comp_len, (unsigned char *) (*compp)->name,
184- strlen((*compp)->name));
185+ s = _libssh2_kex_agree_instr(comp, comp_len,
186+ (unsigned char *) (*compp)->name,
187+ strlen((*compp)->name));
188 if(s) {
189 endpoint->comp = *compp;
190 return 0;
191@@ -3856,7 +3872,8 @@ _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
192 session->local.kexinit = key_state->oldlocal;
193 session->local.kexinit_len = key_state->oldlocal_len;
194 key_state->state = libssh2_NB_state_idle;
195- session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
196+ session->state &= ~LIBSSH2_STATE_INITIAL_KEX;
197+ session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
198 session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
199 return -1;
200 }
201@@ -3904,6 +3921,7 @@ _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
202 session->remote.kexinit = NULL;
203 }
204
205+ session->state &= ~LIBSSH2_STATE_INITIAL_KEX;
206 session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
207 session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
208
209diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h
210index da488b7..7faeab6 100644
211--- a/src/libssh2_priv.h
212+++ b/src/libssh2_priv.h
213@@ -640,6 +640,9 @@ struct _LIBSSH2_SESSION
214 unsigned char server_hostkey_sha256[SHA256_DIGEST_LENGTH];
215 int server_hostkey_sha256_valid;
216
217+ /* Whether to use the OpenSSH Strict KEX extension */
218+ int kex_strict;
219+
220 /* (remote as source of data -- packet_read ) */
221 libssh2_endpoint_data remote;
222
223@@ -809,6 +812,7 @@ struct _LIBSSH2_SESSION
224 int fullpacket_macstate;
225 size_t fullpacket_payload_len;
226 int fullpacket_packet_type;
227+ uint32_t fullpacket_required_type;
228
229 /* State variables used in libssh2_sftp_init() */
230 libssh2_nonblocking_states sftpInit_state;
231@@ -856,10 +860,11 @@ struct _LIBSSH2_SESSION
232 };
233
234 /* session.state bits */
235-#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000001
236-#define LIBSSH2_STATE_NEWKEYS 0x00000002
237-#define LIBSSH2_STATE_AUTHENTICATED 0x00000004
238-#define LIBSSH2_STATE_KEX_ACTIVE 0x00000008
239+#define LIBSSH2_STATE_INITIAL_KEX 0x00000001
240+#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000002
241+#define LIBSSH2_STATE_NEWKEYS 0x00000004
242+#define LIBSSH2_STATE_AUTHENTICATED 0x00000008
243+#define LIBSSH2_STATE_KEX_ACTIVE 0x00000010
244
245 /* session.flag helpers */
246 #ifdef MSG_NOSIGNAL
247@@ -1076,6 +1081,11 @@ ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer,
248 int _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
249 key_exchange_state_t * state);
250
251+unsigned char *_libssh2_kex_agree_instr(unsigned char *haystack,
252+ size_t haystack_len,
253+ const unsigned char *needle,
254+ size_t needle_len);
255+
256 /* Let crypt.c/hostkey.c expose their method structs */
257 const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void);
258 const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void);
259diff --git a/src/packet.c b/src/packet.c
260index 04937d6..786ba40 100644
261--- a/src/packet.c
262+++ b/src/packet.c
263@@ -467,14 +467,13 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
264 * layer when it has received a packet.
265 *
266 * The input pointer 'data' is pointing to allocated data that this function
267- * is asked to deal with so on failure OR success, it must be freed fine.
268- * The only exception is when the return code is LIBSSH2_ERROR_EAGAIN.
269+ * will be freed unless return the code is LIBSSH2_ERROR_EAGAIN.
270 *
271 * This function will always be called with 'datalen' greater than zero.
272 */
273 int
274 _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
275- size_t datalen, int macstate)
276+ size_t datalen, int macstate, uint32_t seq)
277 {
278 int rc = 0;
279 unsigned char *message = NULL;
280@@ -517,6 +516,70 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
281 break;
282 }
283
284+ if(session->state & LIBSSH2_STATE_INITIAL_KEX) {
285+ if(msg == SSH_MSG_KEXINIT) {
286+ if(!session->kex_strict) {
287+ if(datalen < 17) {
288+ LIBSSH2_FREE(session, data);
289+ session->packAdd_state = libssh2_NB_state_idle;
290+ return _libssh2_error(session,
291+ LIBSSH2_ERROR_BUFFER_TOO_SMALL,
292+ "Data too short extracting kex");
293+ }
294+ else {
295+ const unsigned char *strict =
296+ (unsigned char *)"kex-strict-s-v00@openssh.com";
297+ struct string_buf buf;
298+ unsigned char *algs = NULL;
299+ size_t algs_len = 0;
300+
301+ buf.data = (unsigned char *)data;
302+ buf.dataptr = buf.data;
303+ buf.len = datalen;
304+ buf.dataptr += 17; /* advance past type and cookie */
305+
306+ if(_libssh2_get_string(&buf, &algs, &algs_len)) {
307+ LIBSSH2_FREE(session, data);
308+ session->packAdd_state = libssh2_NB_state_idle;
309+ return _libssh2_error(session,
310+ LIBSSH2_ERROR_BUFFER_TOO_SMALL,
311+ "Algs too short");
312+ }
313+
314+ if(algs_len == 0 ||
315+ _libssh2_kex_agree_instr(algs, algs_len, strict, 28)) {
316+ session->kex_strict = 1;
317+ }
318+ }
319+ }
320+
321+ if(session->kex_strict && seq) {
322+ LIBSSH2_FREE(session, data);
323+ session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
324+ session->packAdd_state = libssh2_NB_state_idle;
325+ libssh2_session_disconnect(session, "strict KEX violation: "
326+ "KEXINIT was not the first packet");
327+
328+ return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
329+ "strict KEX violation: "
330+ "KEXINIT was not the first packet");
331+ }
332+ }
333+
334+ if(session->kex_strict && session->fullpacket_required_type &&
335+ session->fullpacket_required_type != msg) {
336+ LIBSSH2_FREE(session, data);
337+ session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
338+ session->packAdd_state = libssh2_NB_state_idle;
339+ libssh2_session_disconnect(session, "strict KEX violation: "
340+ "unexpected packet type");
341+
342+ return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
343+ "strict KEX violation: "
344+ "unexpected packet type");
345+ }
346+ }
347+
348 if(session->packAdd_state == libssh2_NB_state_allocated) {
349 /* A couple exceptions to the packet adding rule: */
350 switch(msg) {
351@@ -1118,7 +1181,16 @@ _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
352
353 return 0;
354 }
355- packet = _libssh2_list_next(&packet->node);
356+ else if(session->kex_strict &&
357+ (session->state & LIBSSH2_STATE_INITIAL_KEX)) {
358+ libssh2_session_disconnect(session, "strict KEX violation: "
359+ "unexpected packet type");
360+
361+ return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
362+ "strict KEX violation: "
363+ "unexpected packet type");
364+ }
365+ packet = _libssh2_list_next(&packet->node);
366 }
367 return -1;
368 }
369@@ -1179,7 +1251,10 @@ _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
370 }
371
372 while(session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
373- int ret = _libssh2_transport_read(session);
374+ int ret;
375+ session->fullpacket_required_type = packet_type;
376+ ret = _libssh2_transport_read(session);
377+ session->fullpacket_required_type = 0;
378 if(ret == LIBSSH2_ERROR_EAGAIN)
379 return ret;
380 else if(ret < 0) {
381diff --git a/src/packet.h b/src/packet.h
382index 79018bc..08ea2a2 100644
383--- a/src/packet.h
384+++ b/src/packet.h
385@@ -71,6 +71,6 @@ int _libssh2_packet_burn(LIBSSH2_SESSION * session,
386 int _libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
387 unsigned long data_len);
388 int _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
389- size_t datalen, int macstate);
390+ size_t datalen, int macstate, uint32_t seq);
391
392 #endif /* __LIBSSH2_PACKET_H */
393diff --git a/src/session.c b/src/session.c
394index 212560b..019b9ed 100644
395--- a/src/session.c
396+++ b/src/session.c
397@@ -500,6 +500,8 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
398 session->abstract = abstract;
399 session->api_timeout = 0; /* timeout-free API by default */
400 session->api_block_mode = 1; /* blocking API by default */
401+ session->state = LIBSSH2_STATE_INITIAL_KEX;
402+ session->fullpacket_required_type = 0;
403 _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
404 "New session resource allocated");
405 _libssh2_init_if_needed();
406@@ -1171,6 +1173,7 @@ libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason,
407 const char *desc, const char *lang)
408 {
409 int rc;
410+ session->state &= ~LIBSSH2_STATE_INITIAL_KEX;
411 session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
412 BLOCK_ADJUST(rc, session,
413 session_disconnect(session, reason, desc, lang));
414diff --git a/src/transport.c b/src/transport.c
415index 1074fc2..6823b63 100644
416--- a/src/transport.c
417+++ b/src/transport.c
418@@ -168,6 +168,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
419 struct transportpacket *p = &session->packet;
420 int rc;
421 int compressed;
422+ uint32_t seq = session->remote.seqno;
423
424 if(session->fullpacket_state == libssh2_NB_state_idle) {
425 session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED;
426@@ -240,7 +241,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
427 if(session->fullpacket_state == libssh2_NB_state_created) {
428 rc = _libssh2_packet_add(session, p->payload,
429 session->fullpacket_payload_len,
430- session->fullpacket_macstate);
431+ session->fullpacket_macstate, seq);
432 if(rc == LIBSSH2_ERROR_EAGAIN)
433 return rc;
434 if(rc) {
435@@ -251,6 +252,11 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
436
437 session->fullpacket_state = libssh2_NB_state_idle;
438
439+ if(session->kex_strict &&
440+ session->fullpacket_packet_type == SSH_MSG_NEWKEYS) {
441+ session->remote.seqno = 0;
442+ }
443+
444 return session->fullpacket_packet_type;
445 }
446
447@@ -892,6 +898,10 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
448
449 session->local.seqno++;
450
451+ if(session->kex_strict && data[0] == SSH_MSG_NEWKEYS) {
452+ session->local.seqno = 0;
453+ }
454+
455 ret = LIBSSH2_SEND(session, p->outbuf, total_length,
456 LIBSSH2_SOCKET_SEND_FLAGS(session));
457 if(ret < 0)
458--
4592.40.0
diff --git a/meta/recipes-support/libssh2/libssh2_1.10.0.bb b/meta/recipes-support/libssh2/libssh2_1.10.0.bb
index 8483a292c2..8fd77996d5 100644
--- a/meta/recipes-support/libssh2/libssh2_1.10.0.bb
+++ b/meta/recipes-support/libssh2/libssh2_1.10.0.bb
@@ -11,6 +11,7 @@ SRC_URI = "http://www.libssh2.org/download/${BP}.tar.gz \
11 file://fix-ssh2-test.patch \ 11 file://fix-ssh2-test.patch \
12 file://run-ptest \ 12 file://run-ptest \
13 file://CVE-2020-22218.patch \ 13 file://CVE-2020-22218.patch \
14 file://CVE-2023-48795.patch \
14 " 15 "
15 16
16SRC_URI[sha256sum] = "2d64e90f3ded394b91d3a2e774ca203a4179f69aebee03003e5a6fa621e41d51" 17SRC_URI[sha256sum] = "2d64e90f3ded394b91d3a2e774ca203a4179f69aebee03003e5a6fa621e41d51"