<p>Raul Rangel has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/25411">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">src/include/hexutil.h: Add converters for working with hex strings<br><br>These utilities will be used as part of fixing SMBIOS generation for<br>soc/amd.<br><br>I have a bunch of unit tests for these functions outside of this commit. Is<br>there somewhere I can commit them?<br><br>BUG=b:65403853<br>TEST=tested on grunt<br><br>Change-Id: Ifcabf09be4dc053f8b6e132b4014380cdb5c521b<br>Signed-off-by: Raul E Rangel <rrangel@chromium.org><br>---<br>A src/include/hexutil.h<br>M src/lib/Makefile.inc<br>A src/lib/hexutil.c<br>3 files changed, 137 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/11/25411/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/include/hexutil.h b/src/include/hexutil.h</span><br><span>new file mode 100644</span><br><span>index 0000000..847d39c</span><br><span>--- /dev/null</span><br><span>+++ b/src/include/hexutil.h</span><br><span>@@ -0,0 +1,55 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018 Google LLC.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef HEXUTIL_H</span><br><span style="color: hsl(120, 100%, 40%);">+#define HEXUTIL_H</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stddef.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Decodes a hex character [0-9A-Za-z] into a byte.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Invalid characters are mapped to 0.</span><br><span style="color: hsl(120, 100%, 40%);">+ * */</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t decode_hex_character(char hex);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Decodes a hex string into a byte array.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Examples:</span><br><span style="color: hsl(120, 100%, 40%);">+ *  * "01AF" => {0x01, 0xAF}</span><br><span style="color: hsl(120, 100%, 40%);">+ *  * "1AF" => {0x01, 0xAF}</span><br><span style="color: hsl(120, 100%, 40%);">+ *  * "1AF" => {0x00, 0x00, 0x01, 0xAF} w/ 4 byte dest buffer.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @param src_size size of the src buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ * @param dest_size must be at least (strlen(src) + 1) / 2 in size. If the</span><br><span style="color: hsl(120, 100%, 40%);">+ * buffer is bigger than required the most significant bytes are cleared.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void decode_hex_string(const char *src, size_t src_size, uint8_t *dest,</span><br><span style="color: hsl(120, 100%, 40%);">+                    size_t dest_size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Encodes a byte array into a hex string.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * e.g., {0x01, 0x02} => "0102"</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @param dest_size must be at least (src_size * 2 + 1). If it is smaller, the</span><br><span style="color: hsl(120, 100%, 40%);">+ * least significant bytes will be truncated.</span><br><span style="color: hsl(120, 100%, 40%);">+ * @return number of characters written excluding the null terminator.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+size_t encode_as_hex_string(const uint8_t *src, size_t src_size, char *dest,</span><br><span style="color: hsl(120, 100%, 40%);">+                    size_t dest_size);</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span>diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc</span><br><span>index 960b5cb..3ae77a6 100644</span><br><span>--- a/src/lib/Makefile.inc</span><br><span>+++ b/src/lib/Makefile.inc</span><br><span>@@ -133,6 +133,7 @@</span><br><span> ramstage-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c</span><br><span> ramstage-$(CONFIG_GENERIC_UDELAY) += timer.c</span><br><span> ramstage-y += b64_decode.c</span><br><span style="color: hsl(120, 100%, 40%);">+ramstage-y += hexutil.c</span><br><span> ramstage-$(CONFIG_ACPI_NHLT) += nhlt.c</span><br><span> </span><br><span> romstage-y += cbmem_common.c</span><br><span>diff --git a/src/lib/hexutil.c b/src/lib/hexutil.c</span><br><span>new file mode 100644</span><br><span>index 0000000..a41a94a</span><br><span>--- /dev/null</span><br><span>+++ b/src/lib/hexutil.c</span><br><span>@@ -0,0 +1,81 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018 Google LLC.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <hexutil.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t decode_hex_character(char hex)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      if (isdigit(hex))</span><br><span style="color: hsl(120, 100%, 40%);">+             return hex - '0';</span><br><span style="color: hsl(120, 100%, 40%);">+     else if (isxdigit(hex) && isupper(hex))</span><br><span style="color: hsl(120, 100%, 40%);">+               return hex - 'A' + 10;</span><br><span style="color: hsl(120, 100%, 40%);">+        else if (isxdigit(hex) && islower(hex))</span><br><span style="color: hsl(120, 100%, 40%);">+               return hex - 'a' + 10;</span><br><span style="color: hsl(120, 100%, 40%);">+        else</span><br><span style="color: hsl(120, 100%, 40%);">+          return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void decode_hex_string(const char *src, size_t src_size, uint8_t *dest,</span><br><span style="color: hsl(120, 100%, 40%);">+                      size_t dest_size)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   const size_t src_len = strnlen(src, src_size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      for (size_t dest_idx = 0; dest_idx < dest_size; ++dest_idx) {</span><br><span style="color: hsl(120, 100%, 40%);">+              int src_idx = (src_len - 1) - dest_idx * 2;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         uint8_t byte = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (src_idx >= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        char low = src[src_idx];</span><br><span style="color: hsl(120, 100%, 40%);">+                      byte |= decode_hex_character(low);</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (src_idx >= 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        char high = src[src_idx - 1];</span><br><span style="color: hsl(120, 100%, 40%);">+                 byte |= decode_hex_character(high) << 4;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           dest[(dest_size - 1) - dest_idx] = byte;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+size_t encode_as_hex_string(const uint8_t *src, size_t src_size, char *dest,</span><br><span style="color: hsl(120, 100%, 40%);">+                    size_t dest_size)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        size_t cnt = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (src_size == 0 && dest_size > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                dest[0] = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     for (size_t src_idx = 0; src_idx < src_size; ++src_idx) {</span><br><span style="color: hsl(120, 100%, 40%);">+          size_t dest_offset = src_idx * 2;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (dest_offset + 3 <= dest_size) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        snprintf(dest + dest_offset, 3, "%02hhx", src[src_idx]);</span><br><span style="color: hsl(120, 100%, 40%);">+                    cnt += 2;</span><br><span style="color: hsl(120, 100%, 40%);">+             } else if (dest_offset + 2 <= dest_size) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 snprintf(dest + dest_offset, 2, "%hhx",</span><br><span style="color: hsl(120, 100%, 40%);">+                              src[src_idx] >> 4);</span><br><span style="color: hsl(120, 100%, 40%);">+                    cnt += 1;</span><br><span style="color: hsl(120, 100%, 40%);">+             } else if (dest_offset < dest_size) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      dest[dest_offset] = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   break;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return cnt;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/25411">change 25411</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/25411"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Ifcabf09be4dc053f8b6e132b4014380cdb5c521b </div>
<div style="display:none"> Gerrit-Change-Number: 25411 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Raul Rangel <rrangel@chromium.org> </div>