VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
b4d0d230ccfb5 (Thomas Gleixner 2019-05-20 19:08:01 +0200   1) // SPDX-License-Identifier: GPL-2.0-or-later
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100   2) /* ASN.1 Object identifier (OID) registry
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100   3)  *
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100   4)  * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100   5)  * Written by David Howells (dhowells@redhat.com)
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100   6)  */
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100   7) 
9e6879460c8ed (David Howells   2013-05-04 08:48:27 +0100   8) #include <linux/module.h>
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100   9) #include <linux/export.h>
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  10) #include <linux/oid_registry.h>
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100  11) #include <linux/kernel.h>
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100  12) #include <linux/errno.h>
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100  13) #include <linux/bug.h>
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400  14) #include <linux/asn1.h>
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  15) #include "oid_registry_data.c"
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  16) 
9e6879460c8ed (David Howells   2013-05-04 08:48:27 +0100  17) MODULE_DESCRIPTION("OID Registry");
9e6879460c8ed (David Howells   2013-05-04 08:48:27 +0100  18) MODULE_AUTHOR("Red Hat, Inc.");
9e6879460c8ed (David Howells   2013-05-04 08:48:27 +0100  19) MODULE_LICENSE("GPL");
9e6879460c8ed (David Howells   2013-05-04 08:48:27 +0100  20) 
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  21) /**
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  22)  * look_up_OID - Find an OID registration for the specified data
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  23)  * @data: Binary representation of the OID
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  24)  * @datasize: Size of the binary representation
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  25)  */
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  26) enum OID look_up_OID(const void *data, size_t datasize)
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  27) {
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  28) 	const unsigned char *octets = data;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  29) 	enum OID oid;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  30) 	unsigned char xhash;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  31) 	unsigned i, j, k, hash;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  32) 	size_t len;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  33) 
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  34) 	/* Hash the OID data */
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  35) 	hash = datasize - 1;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  36) 
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  37) 	for (i = 0; i < datasize; i++)
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  38) 		hash += octets[i] * 33;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  39) 	hash = (hash >> 24) ^ (hash >> 16) ^ (hash >> 8) ^ hash;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  40) 	hash &= 0xff;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  41) 
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  42) 	/* Binary search the OID registry.  OIDs are stored in ascending order
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  43) 	 * of hash value then ascending order of size and then in ascending
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  44) 	 * order of reverse value.
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  45) 	 */
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  46) 	i = 0;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  47) 	k = OID__NR;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  48) 	while (i < k) {
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  49) 		j = (i + k) / 2;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  50) 
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  51) 		xhash = oid_search_table[j].hash;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  52) 		if (xhash > hash) {
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  53) 			k = j;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  54) 			continue;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  55) 		}
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  56) 		if (xhash < hash) {
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  57) 			i = j + 1;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  58) 			continue;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  59) 		}
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  60) 
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  61) 		oid = oid_search_table[j].oid;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  62) 		len = oid_index[oid + 1] - oid_index[oid];
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  63) 		if (len > datasize) {
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  64) 			k = j;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  65) 			continue;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  66) 		}
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  67) 		if (len < datasize) {
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  68) 			i = j + 1;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  69) 			continue;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  70) 		}
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  71) 
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  72) 		/* Variation is most likely to be at the tail end of the
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  73) 		 * OID, so do the comparison in reverse.
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  74) 		 */
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  75) 		while (len > 0) {
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  76) 			unsigned char a = oid_data[oid_index[oid] + --len];
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  77) 			unsigned char b = octets[len];
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  78) 			if (a > b) {
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  79) 				k = j;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  80) 				goto next;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  81) 			}
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  82) 			if (a < b) {
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  83) 				i = j + 1;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  84) 				goto next;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  85) 			}
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  86) 		}
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  87) 		return oid;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  88) 	next:
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  89) 		;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  90) 	}
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  91) 
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  92) 	return OID__NR;
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  93) }
a77ad6ea0b0bb (David Howells   2012-09-21 23:30:46 +0100  94) EXPORT_SYMBOL_GPL(look_up_OID);
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100  95) 
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400  96) /**
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400  97)  * parse_OID - Parse an OID from a bytestream
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400  98)  * @data: Binary representation of the header + OID
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400  99)  * @datasize: Size of the binary representation
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 100)  * @oid: Pointer to oid to return result
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 101)  *
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 102)  * Parse an OID from a bytestream that holds the OID in the format
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 103)  * ASN1_OID | length | oid. The length indicator must equal to datasize - 2.
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 104)  * -EBADMSG is returned if the bytestream is too short.
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 105)  */
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 106) int parse_OID(const void *data, size_t datasize, enum OID *oid)
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 107) {
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 108) 	const unsigned char *v = data;
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 109) 
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 110) 	/* we need 2 bytes of header and at least 1 byte for oid */
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 111) 	if (datasize < 3 || v[0] != ASN1_OID || v[1] != datasize - 2)
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 112) 		return -EBADMSG;
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 113) 
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 114) 	*oid = look_up_OID(data + 2, datasize - 2);
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 115) 	return 0;
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 116) }
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 117) EXPORT_SYMBOL_GPL(parse_OID);
d1a303e8616c5 (Stefan Berger   2021-03-16 17:07:36 -0400 118) 
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 119) /*
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 120)  * sprint_OID - Print an Object Identifier into a buffer
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 121)  * @data: The encoded OID to print
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 122)  * @datasize: The size of the encoded OID
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 123)  * @buffer: The buffer to render into
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 124)  * @bufsize: The size of the buffer
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 125)  *
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 126)  * The OID is rendered into the buffer in "a.b.c.d" format and the number of
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 127)  * bytes is returned.  -EBADMSG is returned if the data could not be intepreted
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 128)  * and -ENOBUFS if the buffer was too small.
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 129)  */
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 130) int sprint_oid(const void *data, size_t datasize, char *buffer, size_t bufsize)
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 131) {
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 132) 	const unsigned char *v = data, *end = v + datasize;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 133) 	unsigned long num;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 134) 	unsigned char n;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 135) 	size_t ret;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 136) 	int count;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 137) 
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 138) 	if (v >= end)
8dfd2f22d3bf3 (Eric Biggers    2017-12-08 15:13:28 +0000 139) 		goto bad;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 140) 
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 141) 	n = *v++;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 142) 	ret = count = snprintf(buffer, bufsize, "%u.%u", n / 40, n % 40);
47e0a208fb9d9 (Eric Biggers    2017-12-08 15:13:28 +0000 143) 	if (count >= bufsize)
47e0a208fb9d9 (Eric Biggers    2017-12-08 15:13:28 +0000 144) 		return -ENOBUFS;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 145) 	buffer += count;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 146) 	bufsize -= count;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 147) 
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 148) 	while (v < end) {
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 149) 		num = 0;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 150) 		n = *v++;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 151) 		if (!(n & 0x80)) {
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 152) 			num = n;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 153) 		} else {
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 154) 			num = n & 0x7f;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 155) 			do {
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 156) 				if (v >= end)
8dfd2f22d3bf3 (Eric Biggers    2017-12-08 15:13:28 +0000 157) 					goto bad;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 158) 				n = *v++;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 159) 				num <<= 7;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 160) 				num |= n & 0x7f;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 161) 			} while (n & 0x80);
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 162) 		}
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 163) 		ret += count = snprintf(buffer, bufsize, ".%lu", num);
47e0a208fb9d9 (Eric Biggers    2017-12-08 15:13:28 +0000 164) 		if (count >= bufsize)
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 165) 			return -ENOBUFS;
47e0a208fb9d9 (Eric Biggers    2017-12-08 15:13:28 +0000 166) 		buffer += count;
afdb05e9d6190 (Takashi Iwai    2017-09-08 16:15:58 -0700 167) 		bufsize -= count;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 168) 	}
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 169) 
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 170) 	return ret;
8dfd2f22d3bf3 (Eric Biggers    2017-12-08 15:13:28 +0000 171) 
8dfd2f22d3bf3 (Eric Biggers    2017-12-08 15:13:28 +0000 172) bad:
8dfd2f22d3bf3 (Eric Biggers    2017-12-08 15:13:28 +0000 173) 	snprintf(buffer, bufsize, "(bad)");
8dfd2f22d3bf3 (Eric Biggers    2017-12-08 15:13:28 +0000 174) 	return -EBADMSG;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 175) }
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 176) EXPORT_SYMBOL_GPL(sprint_oid);
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 177) 
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 178) /**
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 179)  * sprint_OID - Print an Object Identifier into a buffer
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 180)  * @oid: The OID to print
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 181)  * @buffer: The buffer to render into
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 182)  * @bufsize: The size of the buffer
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 183)  *
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 184)  * The OID is rendered into the buffer in "a.b.c.d" format and the number of
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 185)  * bytes is returned.
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 186)  */
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 187) int sprint_OID(enum OID oid, char *buffer, size_t bufsize)
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 188) {
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 189) 	int ret;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 190) 
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 191) 	BUG_ON(oid >= OID__NR);
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 192) 
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 193) 	ret = sprint_oid(oid_data + oid_index[oid],
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 194) 			 oid_index[oid + 1] - oid_index[oid],
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 195) 			 buffer, bufsize);
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 196) 	BUG_ON(ret == -EBADMSG);
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 197) 	return ret;
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 198) }
4f73175d0375a (David Howells   2012-09-21 23:30:51 +0100 199) EXPORT_SYMBOL_GPL(sprint_OID);