LCOV - code coverage report
Current view: top level - lib - oid_registry.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_real_modules_combined.info Lines: 24 60 40.0 %
Date: 2020-09-30 20:25:40 Functions: 1 3 33.3 %
Branches: 14 36 38.9 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-or-later
       2                 :            : /* ASN.1 Object identifier (OID) registry
       3                 :            :  *
       4                 :            :  * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
       5                 :            :  * Written by David Howells (dhowells@redhat.com)
       6                 :            :  */
       7                 :            : 
       8                 :            : #include <linux/module.h>
       9                 :            : #include <linux/export.h>
      10                 :            : #include <linux/oid_registry.h>
      11                 :            : #include <linux/kernel.h>
      12                 :            : #include <linux/errno.h>
      13                 :            : #include <linux/bug.h>
      14                 :            : #include "oid_registry_data.c"
      15                 :            : 
      16                 :            : MODULE_DESCRIPTION("OID Registry");
      17                 :            : MODULE_AUTHOR("Red Hat, Inc.");
      18                 :            : MODULE_LICENSE("GPL");
      19                 :            : 
      20                 :            : /**
      21                 :            :  * look_up_OID - Find an OID registration for the specified data
      22                 :            :  * @data: Binary representation of the OID
      23                 :            :  * @datasize: Size of the binary representation
      24                 :            :  */
      25                 :       4347 : enum OID look_up_OID(const void *data, size_t datasize)
      26                 :            : {
      27                 :            :         const unsigned char *octets = data;
      28                 :            :         enum OID oid;
      29                 :            :         unsigned char xhash;
      30                 :            :         unsigned i, j, k, hash;
      31                 :            :         size_t len;
      32                 :            : 
      33                 :            :         /* Hash the OID data */
      34                 :       4347 :         hash = datasize - 1;
      35                 :            : 
      36         [ +  + ]:      37260 :         for (i = 0; i < datasize; i++)
      37                 :      32913 :                 hash += octets[i] * 33;
      38                 :       4347 :         hash = (hash >> 24) ^ (hash >> 16) ^ (hash >> 8) ^ hash;
      39                 :       4347 :         hash &= 0xff;
      40                 :            : 
      41                 :            :         /* Binary search the OID registry.  OIDs are stored in ascending order
      42                 :            :          * of hash value then ascending order of size and then in ascending
      43                 :            :          * order of reverse value.
      44                 :            :          */
      45                 :            :         i = 0;
      46                 :            :         k = OID__NR;
      47         [ +  - ]:      25875 :         while (i < k) {
      48                 :      21528 :                 j = (i + k) / 2;
      49                 :            : 
      50                 :      21528 :                 xhash = oid_search_table[j].hash;
      51         [ +  + ]:      21528 :                 if (xhash > hash) {
      52                 :            :                         k = j;
      53                 :       8694 :                         continue;
      54                 :            :                 }
      55         [ +  + ]:      12834 :                 if (xhash < hash) {
      56                 :       8073 :                         i = j + 1;
      57                 :       8073 :                         continue;
      58                 :            :                 }
      59                 :            : 
      60                 :       4761 :                 oid = oid_search_table[j].oid;
      61                 :       4761 :                 len = oid_index[oid + 1] - oid_index[oid];
      62         [ -  + ]:       4761 :                 if (len > datasize) {
      63                 :            :                         k = j;
      64                 :          0 :                         continue;
      65                 :            :                 }
      66         [ -  + ]:       4761 :                 if (len < datasize) {
      67                 :          0 :                         i = j + 1;
      68                 :          0 :                         continue;
      69                 :            :                 }
      70                 :            : 
      71                 :            :                 /* Variation is most likely to be at the tail end of the
      72                 :            :                  * OID, so do the comparison in reverse.
      73                 :            :                  */
      74         [ +  + ]:      37674 :                 while (len > 0) {
      75                 :      33327 :                         unsigned char a = oid_data[oid_index[oid] + --len];
      76                 :      33327 :                         unsigned char b = octets[len];
      77         [ +  + ]:      33327 :                         if (a > b) {
      78                 :            :                                 k = j;
      79                 :            :                                 goto next;
      80                 :            :                         }
      81         [ +  - ]:      32913 :                         if (a < b) {
      82                 :          0 :                                 i = j + 1;
      83                 :          0 :                                 goto next;
      84                 :            :                         }
      85                 :            :                 }
      86                 :       4347 :                 return oid;
      87                 :            :         next:
      88                 :            :                 ;
      89                 :            :         }
      90                 :            : 
      91                 :            :         return OID__NR;
      92                 :            : }
      93                 :            : EXPORT_SYMBOL_GPL(look_up_OID);
      94                 :            : 
      95                 :            : /*
      96                 :            :  * sprint_OID - Print an Object Identifier into a buffer
      97                 :            :  * @data: The encoded OID to print
      98                 :            :  * @datasize: The size of the encoded OID
      99                 :            :  * @buffer: The buffer to render into
     100                 :            :  * @bufsize: The size of the buffer
     101                 :            :  *
     102                 :            :  * The OID is rendered into the buffer in "a.b.c.d" format and the number of
     103                 :            :  * bytes is returned.  -EBADMSG is returned if the data could not be intepreted
     104                 :            :  * and -ENOBUFS if the buffer was too small.
     105                 :            :  */
     106                 :          0 : int sprint_oid(const void *data, size_t datasize, char *buffer, size_t bufsize)
     107                 :            : {
     108                 :          0 :         const unsigned char *v = data, *end = v + datasize;
     109                 :            :         unsigned long num;
     110                 :            :         unsigned char n;
     111                 :            :         size_t ret;
     112                 :            :         int count;
     113                 :            : 
     114         [ #  # ]:          0 :         if (v >= end)
     115                 :            :                 goto bad;
     116                 :            : 
     117                 :          0 :         n = *v++;
     118                 :          0 :         ret = count = snprintf(buffer, bufsize, "%u.%u", n / 40, n % 40);
     119         [ #  # ]:          0 :         if (count >= bufsize)
     120                 :            :                 return -ENOBUFS;
     121                 :          0 :         buffer += count;
     122                 :          0 :         bufsize -= count;
     123                 :            : 
     124         [ #  # ]:          0 :         while (v < end) {
     125                 :            :                 num = 0;
     126                 :          0 :                 n = *v++;
     127         [ #  # ]:          0 :                 if (!(n & 0x80)) {
     128                 :          0 :                         num = n;
     129                 :            :                 } else {
     130                 :          0 :                         num = n & 0x7f;
     131                 :            :                         do {
     132         [ #  # ]:          0 :                                 if (v >= end)
     133                 :            :                                         goto bad;
     134                 :          0 :                                 n = *v++;
     135                 :          0 :                                 num <<= 7;
     136                 :          0 :                                 num |= n & 0x7f;
     137         [ #  # ]:          0 :                         } while (n & 0x80);
     138                 :            :                 }
     139                 :          0 :                 ret += count = snprintf(buffer, bufsize, ".%lu", num);
     140         [ #  # ]:          0 :                 if (count >= bufsize)
     141                 :            :                         return -ENOBUFS;
     142                 :          0 :                 buffer += count;
     143                 :          0 :                 bufsize -= count;
     144                 :            :         }
     145                 :            : 
     146                 :          0 :         return ret;
     147                 :            : 
     148                 :            : bad:
     149                 :          0 :         snprintf(buffer, bufsize, "(bad)");
     150                 :          0 :         return -EBADMSG;
     151                 :            : }
     152                 :            : EXPORT_SYMBOL_GPL(sprint_oid);
     153                 :            : 
     154                 :            : /**
     155                 :            :  * sprint_OID - Print an Object Identifier into a buffer
     156                 :            :  * @oid: The OID to print
     157                 :            :  * @buffer: The buffer to render into
     158                 :            :  * @bufsize: The size of the buffer
     159                 :            :  *
     160                 :            :  * The OID is rendered into the buffer in "a.b.c.d" format and the number of
     161                 :            :  * bytes is returned.
     162                 :            :  */
     163                 :          0 : int sprint_OID(enum OID oid, char *buffer, size_t bufsize)
     164                 :            : {
     165                 :            :         int ret;
     166                 :            : 
     167         [ #  # ]:          0 :         BUG_ON(oid >= OID__NR);
     168                 :            : 
     169                 :          0 :         ret = sprint_oid(oid_data + oid_index[oid],
     170                 :          0 :                          oid_index[oid + 1] - oid_index[oid],
     171                 :            :                          buffer, bufsize);
     172         [ #  # ]:          0 :         BUG_ON(ret == -EBADMSG);
     173                 :          0 :         return ret;
     174                 :            : }
     175                 :            : EXPORT_SYMBOL_GPL(sprint_OID);

Generated by: LCOV version 1.14