hc
2024-02-19 890e1df1bec891d9203724541e81f8fbe5183388
kernel/lib/hexdump.c
....@@ -1,16 +1,13 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * lib/hexdump.c
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License version 2 as
6
- * published by the Free Software Foundation. See README and COPYING for
7
- * more details.
84 */
95
106 #include <linux/types.h>
117 #include <linux/ctype.h>
128 #include <linux/errno.h>
139 #include <linux/kernel.h>
10
+#include <linux/minmax.h>
1411 #include <linux/export.h>
1512 #include <asm/unaligned.h>
1613
....@@ -25,15 +22,41 @@
2522 *
2623 * hex_to_bin() converts one hex digit to its actual value or -1 in case of bad
2724 * input.
25
+ *
26
+ * This function is used to load cryptographic keys, so it is coded in such a
27
+ * way that there are no conditions or memory accesses that depend on data.
28
+ *
29
+ * Explanation of the logic:
30
+ * (ch - '9' - 1) is negative if ch <= '9'
31
+ * ('0' - 1 - ch) is negative if ch >= '0'
32
+ * we "and" these two values, so the result is negative if ch is in the range
33
+ * '0' ... '9'
34
+ * we are only interested in the sign, so we do a shift ">> 8"; note that right
35
+ * shift of a negative value is implementation-defined, so we cast the
36
+ * value to (unsigned) before the shift --- we have 0xffffff if ch is in
37
+ * the range '0' ... '9', 0 otherwise
38
+ * we "and" this value with (ch - '0' + 1) --- we have a value 1 ... 10 if ch is
39
+ * in the range '0' ... '9', 0 otherwise
40
+ * we add this value to -1 --- we have a value 0 ... 9 if ch is in the range '0'
41
+ * ... '9', -1 otherwise
42
+ * the next line is similar to the previous one, but we need to decode both
43
+ * uppercase and lowercase letters, so we use (ch & 0xdf), which converts
44
+ * lowercase to uppercase
2845 */
46
+/*
47
+ * perserve abi due to 15b78a8e38e8 ("hex2bin: make the function hex_to_bin
48
+ * constant-time"
49
+ */
50
+#ifdef __GENKSYMS__
2951 int hex_to_bin(char ch)
52
+#else
53
+int hex_to_bin(unsigned char ch)
54
+#endif
3055 {
31
- if ((ch >= '0') && (ch <= '9'))
32
- return ch - '0';
33
- ch = tolower(ch);
34
- if ((ch >= 'a') && (ch <= 'f'))
35
- return ch - 'a' + 10;
36
- return -1;
56
+ unsigned char cu = ch & 0xdf;
57
+ return -1 +
58
+ ((ch - '0' + 1) & (unsigned)((ch - '9' - 1) & ('0' - 1 - ch)) >> 8) +
59
+ ((cu - 'A' + 11) & (unsigned)((cu - 'F' - 1) & ('A' - 1 - cu)) >> 8);
3760 }
3861 EXPORT_SYMBOL(hex_to_bin);
3962
....@@ -48,10 +71,13 @@
4871 int hex2bin(u8 *dst, const char *src, size_t count)
4972 {
5073 while (count--) {
51
- int hi = hex_to_bin(*src++);
52
- int lo = hex_to_bin(*src++);
74
+ int hi, lo;
5375
54
- if ((hi < 0) || (lo < 0))
76
+ hi = hex_to_bin(*src++);
77
+ if (unlikely(hi < 0))
78
+ return -EINVAL;
79
+ lo = hex_to_bin(*src++);
80
+ if (unlikely(lo < 0))
5581 return -EINVAL;
5682
5783 *dst++ = (hi << 4) | lo;
....@@ -274,25 +300,4 @@
274300 }
275301 EXPORT_SYMBOL(print_hex_dump);
276302
277
-#if !defined(CONFIG_DYNAMIC_DEBUG)
278
-/**
279
- * print_hex_dump_bytes - shorthand form of print_hex_dump() with default params
280
- * @prefix_str: string to prefix each line with;
281
- * caller supplies trailing spaces for alignment if desired
282
- * @prefix_type: controls whether prefix of an offset, address, or none
283
- * is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE)
284
- * @buf: data blob to dump
285
- * @len: number of bytes in the @buf
286
- *
287
- * Calls print_hex_dump(), with log level of KERN_DEBUG,
288
- * rowsize of 16, groupsize of 1, and ASCII output included.
289
- */
290
-void print_hex_dump_bytes(const char *prefix_str, int prefix_type,
291
- const void *buf, size_t len)
292
-{
293
- print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, 16, 1,
294
- buf, len, true);
295
-}
296
-EXPORT_SYMBOL(print_hex_dump_bytes);
297
-#endif /* !defined(CONFIG_DYNAMIC_DEBUG) */
298303 #endif /* defined(CONFIG_PRINTK) */