12 #include <linux/export.h>
13 #include <linux/kernel.h>
14 #include <linux/errno.h>
18 static const unsigned char asn1_op_lengths[
ASN1_OP__NR] = {
55 static int asn1_find_indefinite_length(
const unsigned char *
data,
size_t datalen,
56 size_t *_dp,
size_t *_len,
67 goto data_overrun_error;
76 if (--indef_level <= 0) {
84 if (
unlikely((tag & 0x1f) == 0x1f)) {
87 goto data_overrun_error;
102 goto indefinite_len_primitive;
108 if (
unlikely(n >
sizeof(
size_t) - 1))
109 goto length_too_long;
111 goto data_overrun_error;
112 for (len = 0; n > 0; n--) {
120 *_errmsg =
"Unsupported length";
122 indefinite_len_primitive:
123 *_errmsg =
"Indefinite len primitive not permitted";
126 *_errmsg =
"Invalid length EOC";
129 *_errmsg =
"Data overrun error";
132 *_errmsg =
"Missing EOC in indefinite len cons";
165 const unsigned char *data,
170 size_t machlen = decoder->
machlen;
172 unsigned char tag = 0,
csp = 0, jsp = 0, optag = 0,
hdr = 0;
174 size_t pc = 0, dp = 0, tdp = 0, len = 0;
177 unsigned char flags = 0;
178 #define FLAG_INDEFINITE_LENGTH 0x01
179 #define FLAG_MATCHED 0x02
180 #define FLAG_CONS 0x20
185 #define NR_CONS_STACK 10
189 #define NR_JUMP_STACK 10
196 pr_debug(
"next_op: pc=\e[32m%zu\e[m/%zu dp=\e[33m%zu\e[m/%zu C=%d J=%d\n",
197 pc, machlen, dp, datalen,
csp, jsp);
199 goto machine_overrun_error;
201 if (
unlikely(pc + asn1_op_lengths[op] > machlen))
202 goto machine_overrun_error;
214 pc += asn1_op_lengths[
op];
223 goto data_overrun_error;
226 goto long_tag_not_supported;
236 optag = machine[pc + 1];
242 pr_debug(
"- match? %02x %02x %02x\n", tag, optag, tmp);
246 pc += asn1_op_lengths[
op];
253 flags |= FLAG_MATCHED;
260 goto indefinite_len_primitive;
263 goto data_overrun_error;
267 goto length_too_long;
269 goto data_overrun_error;
271 for (len = 0; n > 0; n--) {
276 goto data_overrun_error;
285 goto cons_stack_overflow;
286 cons_dp_stack[
csp] =
dp;
287 cons_hdrlen_stack[
csp] =
hdr;
292 cons_datalen_stack[
csp] = 0;
298 tag, len, flags & FLAG_CONS ?
" CONS" :
"");
327 ret = asn1_find_indefinite_length(
328 data, datalen, &dp, &len, &errmsg);
336 pc += asn1_op_lengths[
op];
344 goto jump_stack_overflow;
345 jump_stack[jsp++] = pc + asn1_op_lengths[
op];
346 pc = machine[pc + 2];
352 pc += asn1_op_lengths[
op];
357 pr_err(
"ASN.1 decoder error: Stacks not empty at completion (%u, %u)\n",
365 if (
unlikely(!(flags & FLAG_MATCHED)))
374 goto cons_stack_underflow;
376 tdp = cons_dp_stack[
csp];
377 hdr = cons_hdrlen_stack[
csp];
379 datalen = cons_datalen_stack[
csp];
380 pr_debug(
"- end cons t=%zu dp=%zu l=%zu/%zu\n",
381 tdp, dp, len, datalen);
386 goto data_overrun_error;
387 if (data[dp++] != 0) {
391 pc = machine[pc + 1];
404 pc = machine[pc + 1];
409 goto cons_length_error;
411 pr_debug(
"- cons len l=%zu d=%zu\n", len, dp - tdp);
417 act = machine[pc + 2];
419 act = machine[pc + 1];
420 ret = actions[act](
context,
hdr, 0, data + tdp, len);
422 pc += asn1_op_lengths[
op];
426 ret = actions[machine[pc + 1]](
context,
hdr,
tag, data + tdp, len);
427 pc += asn1_op_lengths[
op];
432 goto jump_stack_underflow;
433 pc = jump_stack[--jsp];
441 pr_err(
"ASN.1 decoder error: Found reserved opcode (%u)\n", op);
445 errmsg =
"Data overrun error";
447 machine_overrun_error:
448 errmsg =
"Machine overrun error";
450 jump_stack_underflow:
451 errmsg =
"Jump stack underflow";
454 errmsg =
"Jump stack overflow";
456 cons_stack_underflow:
457 errmsg =
"Cons stack underflow";
460 errmsg =
"Cons stack overflow";
463 errmsg =
"Cons length error";
466 errmsg =
"Missing EOC in indefinite len cons";
469 errmsg =
"Invalid length EOC";
472 errmsg =
"Unsupported length";
474 indefinite_len_primitive:
475 errmsg =
"Indefinite len primitive not permitted";
478 errmsg =
"Unexpected tag";
480 long_tag_not_supported:
481 errmsg =
"Long tag not supported";
483 pr_debug(
"\nASN1: %s [m=%zu d=%zu ot=%02x t=%02x l=%zu]\n",
484 errmsg, pc, dp, optag, tag, len);