xref: /linux/drivers/firmware/google/vpd_decode.c (revision b0f84a84fff180718995b1269da2988e5b28be42)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * vpd_decode.c
4  *
5  * Google VPD decoding routines.
6  *
7  * Copyright 2017 Google Inc.
8  */
9 
10 #include <linux/export.h>
11 
12 #include "vpd_decode.h"
13 
14 static int vpd_decode_len(const s32 max_len, const u8 *in,
15 			  s32 *length, s32 *decoded_len)
16 {
17 	u8 more;
18 	int i = 0;
19 
20 	if (!length || !decoded_len)
21 		return VPD_FAIL;
22 
23 	*length = 0;
24 	do {
25 		if (i >= max_len)
26 			return VPD_FAIL;
27 
28 		more = in[i] & 0x80;
29 		*length <<= 7;
30 		*length |= in[i] & 0x7f;
31 		++i;
32 	} while (more);
33 
34 	*decoded_len = i;
35 
36 	return VPD_OK;
37 }
38 
39 int vpd_decode_string(const s32 max_len, const u8 *input_buf, s32 *consumed,
40 		      vpd_decode_callback callback, void *callback_arg)
41 {
42 	int type;
43 	int res;
44 	s32 key_len;
45 	s32 value_len;
46 	s32 decoded_len;
47 	const u8 *key;
48 	const u8 *value;
49 
50 	/* type */
51 	if (*consumed >= max_len)
52 		return VPD_FAIL;
53 
54 	type = input_buf[*consumed];
55 
56 	switch (type) {
57 	case VPD_TYPE_INFO:
58 	case VPD_TYPE_STRING:
59 		(*consumed)++;
60 
61 		/* key */
62 		res = vpd_decode_len(max_len - *consumed, &input_buf[*consumed],
63 				     &key_len, &decoded_len);
64 		if (res != VPD_OK || *consumed + decoded_len >= max_len)
65 			return VPD_FAIL;
66 
67 		*consumed += decoded_len;
68 		key = &input_buf[*consumed];
69 		*consumed += key_len;
70 
71 		/* value */
72 		res = vpd_decode_len(max_len - *consumed, &input_buf[*consumed],
73 				     &value_len, &decoded_len);
74 		if (res != VPD_OK || *consumed + decoded_len > max_len)
75 			return VPD_FAIL;
76 
77 		*consumed += decoded_len;
78 		value = &input_buf[*consumed];
79 		*consumed += value_len;
80 
81 		if (type == VPD_TYPE_STRING)
82 			return callback(key, key_len, value, value_len,
83 					callback_arg);
84 		break;
85 
86 	default:
87 		return VPD_FAIL;
88 	}
89 
90 	return VPD_OK;
91 }
92