Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* Decoder for ASN.1 BER/DER/CER encoded bytestream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/asn1_decoder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/asn1_ber_bytecode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) static const unsigned char asn1_op_lengths[ASN1_OP__NR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 	/*					OPC TAG JMP ACT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	[ASN1_OP_MATCH]				= 1 + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	[ASN1_OP_MATCH_OR_SKIP]			= 1 + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	[ASN1_OP_MATCH_ACT]			= 1 + 1     + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	[ASN1_OP_MATCH_ACT_OR_SKIP]		= 1 + 1     + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	[ASN1_OP_MATCH_JUMP]			= 1 + 1 + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	[ASN1_OP_MATCH_JUMP_OR_SKIP]		= 1 + 1 + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	[ASN1_OP_MATCH_ANY]			= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	[ASN1_OP_MATCH_ANY_OR_SKIP]		= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	[ASN1_OP_MATCH_ANY_ACT]			= 1         + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	[ASN1_OP_MATCH_ANY_ACT_OR_SKIP]		= 1         + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	[ASN1_OP_COND_MATCH_OR_SKIP]		= 1 + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	[ASN1_OP_COND_MATCH_ACT_OR_SKIP]	= 1 + 1     + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	[ASN1_OP_COND_MATCH_JUMP_OR_SKIP]	= 1 + 1 + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	[ASN1_OP_COND_MATCH_ANY]		= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	[ASN1_OP_COND_MATCH_ANY_OR_SKIP]	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	[ASN1_OP_COND_MATCH_ANY_ACT]		= 1         + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	[ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP]	= 1         + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	[ASN1_OP_COND_FAIL]			= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	[ASN1_OP_COMPLETE]			= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	[ASN1_OP_ACT]				= 1         + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	[ASN1_OP_MAYBE_ACT]			= 1         + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	[ASN1_OP_RETURN]			= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	[ASN1_OP_END_SEQ]			= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	[ASN1_OP_END_SEQ_OF]			= 1     + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	[ASN1_OP_END_SET]			= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	[ASN1_OP_END_SET_OF]			= 1     + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	[ASN1_OP_END_SEQ_ACT]			= 1         + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	[ASN1_OP_END_SEQ_OF_ACT]		= 1     + 1 + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	[ASN1_OP_END_SET_ACT]			= 1         + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	[ASN1_OP_END_SET_OF_ACT]		= 1     + 1 + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  * Find the length of an indefinite length object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * @data: The data buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  * @datalen: The end of the innermost containing element in the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * @_dp: The data parse cursor (updated before returning)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * @_len: Where to return the size of the element.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * @_errmsg: Where to return a pointer to an error message on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) static int asn1_find_indefinite_length(const unsigned char *data, size_t datalen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 				       size_t *_dp, size_t *_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 				       const char **_errmsg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	unsigned char tag, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	size_t dp = *_dp, len, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	int indef_level = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) next_tag:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	if (unlikely(datalen - dp < 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		if (datalen == dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 			goto missing_eoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		goto data_overrun_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	/* Extract a tag from the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	tag = data[dp++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	if (tag == ASN1_EOC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		/* It appears to be an EOC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		if (data[dp++] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 			goto invalid_eoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		if (--indef_level <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 			*_len = dp - *_dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			*_dp = dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		goto next_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	if (unlikely((tag & 0x1f) == ASN1_LONG_TAG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			if (unlikely(datalen - dp < 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 				goto data_overrun_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 			tmp = data[dp++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		} while (tmp & 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	/* Extract the length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	len = data[dp++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	if (len <= 0x7f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		goto check_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	if (unlikely(len == ASN1_INDEFINITE_LENGTH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		/* Indefinite length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		if (unlikely((tag & ASN1_CONS_BIT) == ASN1_PRIM << 5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			goto indefinite_len_primitive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		indef_level++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		goto next_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	n = len - 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	if (unlikely(n > sizeof(len) - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		goto length_too_long;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	if (unlikely(n > datalen - dp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		goto data_overrun_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	for (; n > 0; n--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		len <<= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		len |= data[dp++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) check_length:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	if (len > datalen - dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		goto data_overrun_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	dp += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	goto next_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) length_too_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	*_errmsg = "Unsupported length";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) indefinite_len_primitive:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	*_errmsg = "Indefinite len primitive not permitted";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) invalid_eoc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	*_errmsg = "Invalid length EOC";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) data_overrun_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	*_errmsg = "Data overrun error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) missing_eoc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	*_errmsg = "Missing EOC in indefinite len cons";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	*_dp = dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  * asn1_ber_decoder - Decoder BER/DER/CER ASN.1 according to pattern
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  * @decoder: The decoder definition (produced by asn1_compiler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  * @context: The caller's context (to be passed to the action functions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  * @data: The encoded data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  * @datalen: The size of the encoded data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  * Decode BER/DER/CER encoded ASN.1 data according to a bytecode pattern
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  * produced by asn1_compiler.  Action functions are called on marked tags to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  * allow the caller to retrieve significant data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)  * LIMITATIONS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)  * To keep down the amount of stack used by this function, the following limits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)  * have been imposed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)  *  (1) This won't handle datalen > 65535 without increasing the size of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)  *	cons stack elements and length_too_long checking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)  *  (2) The stack of constructed types is 10 deep.  If the depth of non-leaf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)  *	constructed types exceeds this, the decode will fail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)  *  (3) The SET type (not the SET OF type) isn't really supported as tracking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)  *	what members of the set have been seen is a pain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) int asn1_ber_decoder(const struct asn1_decoder *decoder,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		     void *context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		     const unsigned char *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		     size_t datalen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	const unsigned char *machine = decoder->machine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	const asn1_action_t *actions = decoder->actions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	size_t machlen = decoder->machlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	enum asn1_opcode op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	unsigned char tag = 0, csp = 0, jsp = 0, optag = 0, hdr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	const char *errmsg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	size_t pc = 0, dp = 0, tdp = 0, len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	unsigned char flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define FLAG_INDEFINITE_LENGTH	0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define FLAG_MATCHED		0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define FLAG_LAST_MATCHED	0x04 /* Last tag matched */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define FLAG_CONS		0x20 /* Corresponds to CONS bit in the opcode tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 				      * - ie. whether or not we are going to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 				      *   a compound type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 				      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define NR_CONS_STACK 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	unsigned short cons_dp_stack[NR_CONS_STACK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	unsigned short cons_datalen_stack[NR_CONS_STACK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	unsigned char cons_hdrlen_stack[NR_CONS_STACK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #define NR_JUMP_STACK 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	unsigned char jump_stack[NR_JUMP_STACK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	if (datalen > 65535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) next_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	pr_debug("next_op: pc=\e[32m%zu\e[m/%zu dp=\e[33m%zu\e[m/%zu C=%d J=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		 pc, machlen, dp, datalen, csp, jsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	if (unlikely(pc >= machlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		goto machine_overrun_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	op = machine[pc];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	if (unlikely(pc + asn1_op_lengths[op] > machlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		goto machine_overrun_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	/* If this command is meant to match a tag, then do that before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	 * evaluating the command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	if (op <= ASN1_OP__MATCHES_TAG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		unsigned char tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		/* Skip conditional matches if possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		if ((op & ASN1_OP_MATCH__COND && flags & FLAG_MATCHED) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		    (op & ASN1_OP_MATCH__SKIP && dp == datalen)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			flags &= ~FLAG_LAST_MATCHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 			pc += asn1_op_lengths[op];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 			goto next_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		hdr = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		/* Extract a tag from the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		if (unlikely(datalen - dp < 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			goto data_overrun_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		tag = data[dp++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		if (unlikely((tag & 0x1f) == ASN1_LONG_TAG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			goto long_tag_not_supported;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		if (op & ASN1_OP_MATCH__ANY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 			pr_debug("- any %02x\n", tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 			/* Extract the tag from the machine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 			 * - Either CONS or PRIM are permitted in the data if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			 *   CONS is not set in the op stream, otherwise CONS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			 *   is mandatory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			optag = machine[pc + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 			flags |= optag & FLAG_CONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			/* Determine whether the tag matched */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			tmp = optag ^ tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			tmp &= ~(optag & ASN1_CONS_BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 			pr_debug("- match? %02x %02x %02x\n", tag, optag, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 			if (tmp != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 				/* All odd-numbered tags are MATCH_OR_SKIP. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 				if (op & ASN1_OP_MATCH__SKIP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 					pc += asn1_op_lengths[op];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 					dp--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 					goto next_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 				goto tag_mismatch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		flags |= FLAG_MATCHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		len = data[dp++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		if (len > 0x7f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 			if (unlikely(len == ASN1_INDEFINITE_LENGTH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 				/* Indefinite length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 				if (unlikely(!(tag & ASN1_CONS_BIT)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 					goto indefinite_len_primitive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 				flags |= FLAG_INDEFINITE_LENGTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 				if (unlikely(2 > datalen - dp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 					goto data_overrun_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 				int n = len - 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 				if (unlikely(n > 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 					goto length_too_long;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 				if (unlikely(n > datalen - dp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 					goto data_overrun_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 				hdr += n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 				for (len = 0; n > 0; n--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 					len <<= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 					len |= data[dp++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 				if (unlikely(len > datalen - dp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 					goto data_overrun_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			if (unlikely(len > datalen - dp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 				goto data_overrun_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		if (flags & FLAG_CONS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 			/* For expected compound forms, we stack the positions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 			 * of the start and end of the data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 			if (unlikely(csp >= NR_CONS_STACK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 				goto cons_stack_overflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 			cons_dp_stack[csp] = dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 			cons_hdrlen_stack[csp] = hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 			if (!(flags & FLAG_INDEFINITE_LENGTH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 				cons_datalen_stack[csp] = datalen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 				datalen = dp + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 				cons_datalen_stack[csp] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 			csp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		pr_debug("- TAG: %02x %zu%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 			 tag, len, flags & FLAG_CONS ? " CONS" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		tdp = dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	/* Decide how to handle the operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	switch (op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	case ASN1_OP_MATCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	case ASN1_OP_MATCH_OR_SKIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	case ASN1_OP_MATCH_ACT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	case ASN1_OP_MATCH_ACT_OR_SKIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	case ASN1_OP_MATCH_ANY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	case ASN1_OP_MATCH_ANY_OR_SKIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	case ASN1_OP_MATCH_ANY_ACT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	case ASN1_OP_MATCH_ANY_ACT_OR_SKIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	case ASN1_OP_COND_MATCH_OR_SKIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	case ASN1_OP_COND_MATCH_ACT_OR_SKIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	case ASN1_OP_COND_MATCH_ANY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	case ASN1_OP_COND_MATCH_ANY_OR_SKIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	case ASN1_OP_COND_MATCH_ANY_ACT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	case ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		if (!(flags & FLAG_CONS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 			if (flags & FLAG_INDEFINITE_LENGTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 				size_t tmp = dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 				ret = asn1_find_indefinite_length(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 					data, datalen, &tmp, &len, &errmsg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 				if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 					goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 			pr_debug("- LEAF: %zu\n", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		if (op & ASN1_OP_MATCH__ACT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 			unsigned char act;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 			if (op & ASN1_OP_MATCH__ANY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 				act = machine[pc + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 				act = machine[pc + 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 			ret = actions[act](context, hdr, tag, data + dp, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		if (!(flags & FLAG_CONS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 			dp += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		pc += asn1_op_lengths[op];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		goto next_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	case ASN1_OP_MATCH_JUMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	case ASN1_OP_MATCH_JUMP_OR_SKIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	case ASN1_OP_COND_MATCH_JUMP_OR_SKIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		pr_debug("- MATCH_JUMP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		if (unlikely(jsp == NR_JUMP_STACK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 			goto jump_stack_overflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		jump_stack[jsp++] = pc + asn1_op_lengths[op];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		pc = machine[pc + 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		goto next_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	case ASN1_OP_COND_FAIL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		if (unlikely(!(flags & FLAG_MATCHED)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 			goto tag_mismatch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		pc += asn1_op_lengths[op];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		goto next_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	case ASN1_OP_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		if (unlikely(jsp != 0 || csp != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 			pr_err("ASN.1 decoder error: Stacks not empty at completion (%u, %u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			       jsp, csp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 			return -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	case ASN1_OP_END_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	case ASN1_OP_END_SET_ACT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		if (unlikely(!(flags & FLAG_MATCHED)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 			goto tag_mismatch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		/* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	case ASN1_OP_END_SEQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	case ASN1_OP_END_SET_OF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	case ASN1_OP_END_SEQ_OF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	case ASN1_OP_END_SEQ_ACT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	case ASN1_OP_END_SET_OF_ACT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	case ASN1_OP_END_SEQ_OF_ACT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		if (unlikely(csp <= 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 			goto cons_stack_underflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		csp--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		tdp = cons_dp_stack[csp];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		hdr = cons_hdrlen_stack[csp];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		len = datalen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		datalen = cons_datalen_stack[csp];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		pr_debug("- end cons t=%zu dp=%zu l=%zu/%zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 			 tdp, dp, len, datalen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		if (datalen == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 			/* Indefinite length - check for the EOC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			datalen = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			if (unlikely(datalen - dp < 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 				goto data_overrun_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 			if (data[dp++] != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 				if (op & ASN1_OP_END__OF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 					dp--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 					csp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 					pc = machine[pc + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 					pr_debug("- continue\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 					goto next_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 				goto missing_eoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 			if (data[dp++] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 				goto invalid_eoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 			len = dp - tdp - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 			if (dp < len && (op & ASN1_OP_END__OF)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 				datalen = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 				csp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 				pc = machine[pc + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 				pr_debug("- continue\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 				goto next_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 			if (dp != len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 				goto cons_length_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 			len -= tdp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 			pr_debug("- cons len l=%zu d=%zu\n", len, dp - tdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		if (op & ASN1_OP_END__ACT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 			unsigned char act;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 			if (op & ASN1_OP_END__OF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 				act = machine[pc + 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 				act = machine[pc + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 			ret = actions[act](context, hdr, 0, data + tdp, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		pc += asn1_op_lengths[op];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		goto next_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	case ASN1_OP_MAYBE_ACT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		if (!(flags & FLAG_LAST_MATCHED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 			pc += asn1_op_lengths[op];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 			goto next_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		/* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	case ASN1_OP_ACT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		ret = actions[machine[pc + 1]](context, hdr, tag, data + tdp, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		pc += asn1_op_lengths[op];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		goto next_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	case ASN1_OP_RETURN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		if (unlikely(jsp <= 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 			goto jump_stack_underflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		pc = jump_stack[--jsp];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		flags |= FLAG_MATCHED | FLAG_LAST_MATCHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		goto next_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	/* Shouldn't reach here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	pr_err("ASN.1 decoder error: Found reserved opcode (%u) pc=%zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	       op, pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	return -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) data_overrun_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	errmsg = "Data overrun error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) machine_overrun_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	errmsg = "Machine overrun error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) jump_stack_underflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	errmsg = "Jump stack underflow";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) jump_stack_overflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	errmsg = "Jump stack overflow";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) cons_stack_underflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	errmsg = "Cons stack underflow";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) cons_stack_overflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	errmsg = "Cons stack overflow";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) cons_length_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	errmsg = "Cons length error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) missing_eoc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	errmsg = "Missing EOC in indefinite len cons";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) invalid_eoc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	errmsg = "Invalid length EOC";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) length_too_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	errmsg = "Unsupported length";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) indefinite_len_primitive:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	errmsg = "Indefinite len primitive not permitted";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) tag_mismatch:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	errmsg = "Unexpected tag";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) long_tag_not_supported:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	errmsg = "Long tag not supported";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	pr_debug("\nASN1: %s [m=%zu d=%zu ot=%02x t=%02x l=%zu]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		 errmsg, pc, dp, optag, tag, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	return -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) EXPORT_SYMBOL_GPL(asn1_ber_decoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) MODULE_LICENSE("GPL");