Software APIs
hexstr.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include "sw/device/lib/testing/hexstr.h"
6 
7 static const char hex[] = "0123456789abcdef";
8 
9 status_t hexstr_encode(char *dst, size_t dst_size, const void *src,
10  size_t src_size) {
11  const uint8_t *data = (const uint8_t *)src;
12  for (; src_size > 0; --src_size, ++data) {
13  if (dst_size < 3) {
14  return INVALID_ARGUMENT();
15  }
16  *dst++ = hex[*data >> 4];
17  *dst++ = hex[*data & 15];
18  dst_size -= 2;
19  }
20  *dst = '\0';
21  return OK_STATUS();
22 }
23 
24 static status_t decode_nibble(char ch) {
25  if (ch == 0) {
26  // Unexpected end of string.
27  return INVALID_ARGUMENT();
28  }
29  int nibble = (ch >= '0' && ch <= '9') ? ch - '0'
30  : (ch >= 'A' && ch <= 'F') ? ch - 'A' + 10
31  : (ch >= 'a' && ch <= 'f') ? ch - 'a' + 10
32  : -1;
33  if (nibble == -1) {
34  // Not a valid hex digit.
35  return INVALID_ARGUMENT();
36  }
37  return OK_STATUS(nibble);
38 }
39 
40 status_t hexstr_decode(void *dst, size_t dst_size, const char *src) {
41  uint8_t *data = (uint8_t *)dst;
42  while (*src) {
43  if (dst_size == 0) {
44  // Dest buffer too short.
45  return INVALID_ARGUMENT();
46  }
47  // Decode two hex digits the destination byte.
48  uint8_t nibble = (uint8_t)TRY(decode_nibble(*src++));
49  *data = (uint8_t)(nibble << 4);
50  nibble = (uint8_t)TRY(decode_nibble(*src++));
51  *data |= nibble;
52 
53  ++data;
54  --dst_size;
55  }
56  return OK_STATUS();
57 }