brintos

brintos / linux-shallow public Read only

0
0
Text · 1.8 KiB · 5c6f2a7 Raw
99 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * vpd_decode.c4 *5 * Google VPD decoding routines.6 *7 * Copyright 2017 Google Inc.8 */9 10#include "vpd_decode.h"11 12static int vpd_decode_len(const u32 max_len, const u8 *in,13			  u32 *length, u32 *decoded_len)14{15	u8 more;16	int i = 0;17 18	if (!length || !decoded_len)19		return VPD_FAIL;20 21	*length = 0;22	do {23		if (i >= max_len)24			return VPD_FAIL;25 26		more = in[i] & 0x80;27		*length <<= 7;28		*length |= in[i] & 0x7f;29		++i;30	} while (more);31 32	*decoded_len = i;33	return VPD_OK;34}35 36static int vpd_decode_entry(const u32 max_len, const u8 *input_buf,37			    u32 *_consumed, const u8 **entry, u32 *entry_len)38{39	u32 decoded_len;40	u32 consumed = *_consumed;41 42	if (vpd_decode_len(max_len - consumed, &input_buf[consumed],43			   entry_len, &decoded_len) != VPD_OK)44		return VPD_FAIL;45	if (max_len - consumed < decoded_len)46		return VPD_FAIL;47 48	consumed += decoded_len;49	*entry = input_buf + consumed;50 51	/* entry_len is untrusted data and must be checked again. */52	if (max_len - consumed < *entry_len)53		return VPD_FAIL;54 55	consumed += *entry_len;56	*_consumed = consumed;57	return VPD_OK;58}59 60int vpd_decode_string(const u32 max_len, const u8 *input_buf, u32 *consumed,61		      vpd_decode_callback callback, void *callback_arg)62{63	int type;64	u32 key_len;65	u32 value_len;66	const u8 *key;67	const u8 *value;68 69	/* type */70	if (*consumed >= max_len)71		return VPD_FAIL;72 73	type = input_buf[*consumed];74 75	switch (type) {76	case VPD_TYPE_INFO:77	case VPD_TYPE_STRING:78		(*consumed)++;79 80		if (vpd_decode_entry(max_len, input_buf, consumed, &key,81				     &key_len) != VPD_OK)82			return VPD_FAIL;83 84		if (vpd_decode_entry(max_len, input_buf, consumed, &value,85				     &value_len) != VPD_OK)86			return VPD_FAIL;87 88		if (type == VPD_TYPE_STRING)89			return callback(key, key_len, value, value_len,90					callback_arg);91		break;92 93	default:94		return VPD_FAIL;95	}96 97	return VPD_OK;98}99