coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
vpd_decode.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 
3 /*
4  * This is a copy from upstream:
5  * https://chromium.googlesource.com/chromiumos/platform/vpd/+/master/lib/vpd_decode.c
6  */
7 #include "vpd_decode.h"
8 
9 static int vpd_decode_len(
10  const u32 max_len, const u8 *in, u32 *length, u32 *decoded_len)
11 {
12  u8 more;
13  int i = 0;
14 
15  if (!length || !decoded_len)
16  return VPD_DECODE_FAIL;
17 
18  *length = 0;
19  do {
20  if (i >= max_len)
21  return VPD_DECODE_FAIL;
22 
23  more = in[i] & 0x80;
24  *length <<= 7;
25  *length |= in[i] & 0x7f;
26  ++i;
27  } while (more);
28 
29  *decoded_len = i;
30  return VPD_DECODE_OK;
31 }
32 
33 static int vpd_decode_entry(
34  const u32 max_len, const u8 *input_buf, u32 *consumed,
35  const u8 **entry, u32 *entry_len)
36 {
37  u32 decoded_len;
38 
39  if (vpd_decode_len(max_len - *consumed, &input_buf[*consumed],
40  entry_len, &decoded_len) != VPD_DECODE_OK)
41  return VPD_DECODE_FAIL;
42  if (max_len - *consumed < decoded_len)
43  return VPD_DECODE_FAIL;
44 
45  *consumed += decoded_len;
46  *entry = input_buf + *consumed;
47 
48  /* entry_len is untrusted data and must be checked again. */
49  if (max_len - *consumed < *entry_len)
50  return VPD_DECODE_FAIL;
51 
52  *consumed += *entry_len;
53  return VPD_DECODE_OK;
54 }
55 
57  const u32 max_len, const u8 *input_buf, u32 *consumed,
58  vpd_decode_callback callback, void *callback_arg)
59 {
60  int type;
61  u32 key_len;
62  u32 value_len;
63  const u8 *key;
64  const u8 *value;
65 
66  /* type */
67  if (*consumed >= max_len)
68  return VPD_DECODE_FAIL;
69 
70  type = input_buf[*consumed];
71 
72  switch (type) {
73  case VPD_TYPE_INFO:
74  case VPD_TYPE_STRING:
75  (*consumed)++;
76 
77  if (vpd_decode_entry(max_len, input_buf, consumed, &key,
78  &key_len) != VPD_DECODE_OK)
79  return VPD_DECODE_FAIL;
80 
81  if (vpd_decode_entry(max_len, input_buf, consumed, &value,
82  &value_len) != VPD_DECODE_OK)
83  return VPD_DECODE_FAIL;
84 
85  if (type == VPD_TYPE_STRING)
86  return callback(key, key_len, value, value_len,
87  callback_arg);
88  break;
89 
90  default:
91  return VPD_DECODE_FAIL;
92  }
93 
94  return VPD_DECODE_OK;
95 }
pte_t value
Definition: mmu.c:91
uint64_t length
Definition: fw_cfg_if.h:1
unsigned int type
Definition: edid.c:57
uint32_t u32
Definition: stdint.h:51
uint8_t u8
Definition: stdint.h:45
Definition: jpeg.c:27
static int vpd_decode_len(const u32 max_len, const u8 *in, u32 *length, u32 *decoded_len)
Definition: vpd_decode.c:9
int vpd_decode_string(const u32 max_len, const u8 *input_buf, u32 *consumed, vpd_decode_callback callback, void *callback_arg)
Definition: vpd_decode.c:56
static int vpd_decode_entry(const u32 max_len, const u8 *input_buf, u32 *consumed, const u8 **entry, u32 *entry_len)
Definition: vpd_decode.c:33
@ VPD_TYPE_STRING
Definition: vpd_decode.h:20
@ VPD_TYPE_INFO
Definition: vpd_decode.h:21
@ VPD_DECODE_OK
Definition: vpd_decode.h:14
@ VPD_DECODE_FAIL
Definition: vpd_decode.h:15
int vpd_decode_callback(const u8 *key, u32 key_len, const u8 *value, u32 value_len, void *arg)
Definition: vpd_decode.h:26