LCOV - code coverage report
Current view: top level - netinet6 - ip6_id.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 43 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: ip6_id.c,v 1.13 2017/09/08 05:36:53 deraadt Exp $     */
       2             : /*      $NetBSD: ip6_id.c,v 1.7 2003/09/13 21:32:59 itojun Exp $        */
       3             : /*      $KAME: ip6_id.c,v 1.8 2003/09/06 13:41:06 itojun Exp $  */
       4             : 
       5             : /*
       6             :  * Copyright (C) 2003 WIDE Project.
       7             :  * All rights reserved.
       8             :  *
       9             :  * Redistribution and use in source and binary forms, with or without
      10             :  * modification, are permitted provided that the following conditions
      11             :  * are met:
      12             :  * 1. Redistributions of source code must retain the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer.
      14             :  * 2. Redistributions in binary form must reproduce the above copyright
      15             :  *    notice, this list of conditions and the following disclaimer in the
      16             :  *    documentation and/or other materials provided with the distribution.
      17             :  * 3. Neither the name of the project nor the names of its contributors
      18             :  *    may be used to endorse or promote products derived from this software
      19             :  *    without specific prior written permission.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
      22             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
      25             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31             :  * SUCH DAMAGE.
      32             :  */
      33             : 
      34             : /*
      35             :  * Copyright 1998 Niels Provos <provos@citi.umich.edu>
      36             :  * All rights reserved.
      37             :  *
      38             :  * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
      39             :  * such a mathematical system to generate more random (yet non-repeating)
      40             :  * ids to solve the resolver/named problem.  But Niels designed the
      41             :  * actual system based on the constraints.
      42             :  *
      43             :  * Redistribution and use in source and binary forms, with or without
      44             :  * modification, are permitted provided that the following conditions
      45             :  * are met:
      46             :  * 1. Redistributions of source code must retain the above copyright
      47             :  *    notice, this list of conditions and the following disclaimer.
      48             :  * 2. Redistributions in binary form must reproduce the above copyright
      49             :  *    notice, this list of conditions and the following disclaimer in the
      50             :  *    documentation and/or other materials provided with the distribution.
      51             :  *
      52             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      53             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      54             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      55             :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      56             :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      57             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      58             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      59             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      60             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      61             :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      62             :  */
      63             : 
      64             : /*
      65             :  * seed = random (bits - 1) bit
      66             :  * n = prime, g0 = generator to n,
      67             :  * j = random so that gcd(j,n-1) == 1
      68             :  * g = g0^j mod n will be a generator again.
      69             :  *
      70             :  * X[0] = random seed.
      71             :  * X[n] = a*X[n-1]+b mod m is a Linear Congruential Generator
      72             :  * with a = 7^(even random) mod m,
      73             :  *      b = random with gcd(b,m) == 1
      74             :  *      m = constant and a maximal period of m-1.
      75             :  *
      76             :  * The transaction id is determined by:
      77             :  * id[n] = seed xor (g^X[n] mod n)
      78             :  *
      79             :  * Effectivly the id is restricted to the lower (bits - 1) bits, thus
      80             :  * yielding two different cycles by toggling the msb on and off.
      81             :  * This avoids reuse issues caused by reseeding.
      82             :  */
      83             : 
      84             : #include <sys/param.h>
      85             : #include <sys/kernel.h>
      86             : #include <sys/socket.h>
      87             : #include <sys/systm.h>
      88             : 
      89             : #include <netinet/in.h>
      90             : #include <netinet/ip6.h>
      91             : #include <netinet6/ip6_var.h>
      92             : 
      93             : struct randomtab {
      94             :         const int       ru_bits; /* resulting bits */
      95             :         const long      ru_out; /* Time after wich will be reseeded */
      96             :         const u_int32_t ru_max; /* Uniq cycle, avoid blackjack prediction */
      97             :         const u_int32_t ru_gen; /* Starting generator */
      98             :         const u_int32_t ru_n;   /* ru_n: prime, ru_n - 1: product of pfacts[] */
      99             :         const u_int32_t ru_agen; /* determine ru_a as ru_agen^(2*rand) */
     100             :         const u_int32_t ru_m;   /* ru_m = 2^x*3^y */
     101             :         const u_int32_t pfacts[4];      /* factors of ru_n */
     102             : 
     103             :         u_int32_t ru_counter;
     104             :         u_int32_t ru_msb;
     105             : 
     106             :         u_int32_t ru_x;
     107             :         u_int32_t ru_seed, ru_seed2;
     108             :         u_int32_t ru_a, ru_b;
     109             :         u_int32_t ru_g;
     110             :         long ru_reseed;
     111             : };
     112             : 
     113             : static struct randomtab randomtab_20 = {
     114             :         20,                     /* resulting bits */
     115             :         180,                    /* Time after wich will be reseeded */
     116             :         200000,                 /* Uniq cycle, avoid blackjack prediction */
     117             :         2,                      /* Starting generator */
     118             :         524269,                 /* RU_N-1 = 2^2*3^2*14563 */
     119             :         7,                      /* determine ru_a as RU_AGEN^(2*rand) */
     120             :         279936,                 /* RU_M = 2^7*3^7 - don't change */
     121             :         { 2, 3, 14563, 0 },     /* factors of ru_n */
     122             : };
     123             : 
     124             : u_int32_t ip6id_pmod(u_int32_t, u_int32_t, u_int32_t);
     125             : void ip6id_initid(struct randomtab *);
     126             : u_int32_t ip6id_randomid(struct randomtab *);
     127             : 
     128             : /*
     129             :  * Do a fast modular exponation, returned value will be in the range
     130             :  * of 0 - (mod-1)
     131             :  */
     132             : 
     133             : u_int32_t
     134           0 : ip6id_pmod(u_int32_t gen, u_int32_t expo, u_int32_t mod)
     135             : {
     136             :         u_int64_t s, t, u;
     137             : 
     138             :         s = 1;
     139           0 :         t = gen;
     140           0 :         u = expo;
     141             : 
     142           0 :         while (u) {
     143           0 :                 if (u & 1)
     144           0 :                         s = (s * t) % mod;
     145           0 :                 u >>= 1;
     146           0 :                 t = (t * t) % mod;
     147             :         }
     148           0 :         return (s);
     149             : }
     150             : 
     151             : /*
     152             :  * Initializes the seed and chooses a suitable generator. Also toggles
     153             :  * the msb flag. The msb flag is used to generate two distinct
     154             :  * cycles of random numbers and thus avoiding reuse of ids.
     155             :  *
     156             :  * This function is called from id_randomid() when needed, an
     157             :  * application does not have to worry about it.
     158             :  */
     159             : void
     160           0 : ip6id_initid(struct randomtab *p)
     161             : {
     162             :         u_int32_t j, i;
     163             :         int noprime = 1;
     164             : 
     165           0 :         p->ru_x = arc4random_uniform(p->ru_m);
     166             : 
     167             :         /* (bits - 1) bits of random seed */
     168           0 :         p->ru_seed = arc4random() & (~0U >> (32 - p->ru_bits + 1));
     169           0 :         p->ru_seed2 = arc4random() & (~0U >> (32 - p->ru_bits + 1));
     170             : 
     171             :         /* Determine the LCG we use */
     172           0 :         p->ru_b = (arc4random() & (~0U >> (32 - p->ru_bits))) | 1;
     173           0 :         p->ru_a = ip6id_pmod(p->ru_agen,
     174           0 :             (arc4random() & (~0U >> (32 - p->ru_bits))) & (~1U), p->ru_m);
     175           0 :         while (p->ru_b % 3 == 0)
     176           0 :                 p->ru_b += 2;
     177             : 
     178           0 :         j = arc4random_uniform(p->ru_n);
     179             : 
     180             :         /*
     181             :          * Do a fast gcd(j, RU_N - 1), so we can find a j with
     182             :          * gcd(j, RU_N - 1) == 1, giving a new generator for
     183             :          * RU_GEN^j mod RU_N
     184             :          */
     185           0 :         while (noprime) {
     186           0 :                 for (i = 0; p->pfacts[i] > 0; i++)
     187           0 :                         if (j % p->pfacts[i] == 0)
     188             :                                 break;
     189             : 
     190           0 :                 if (p->pfacts[i] == 0)
     191           0 :                         noprime = 0;
     192             :                 else
     193           0 :                         j = (j + 1) % p->ru_n;
     194             :         }
     195             : 
     196           0 :         p->ru_g = ip6id_pmod(p->ru_gen, j, p->ru_n);
     197           0 :         p->ru_counter = 0;
     198             : 
     199           0 :         p->ru_reseed = time_uptime + p->ru_out;
     200           0 :         p->ru_msb = p->ru_msb ? 0 : (1U << (p->ru_bits - 1));
     201           0 : }
     202             : 
     203             : u_int32_t
     204           0 : ip6id_randomid(struct randomtab *p)
     205             : {
     206             :         int i, n;
     207             : 
     208           0 :         if (p->ru_counter >= p->ru_max || time_uptime > p->ru_reseed)
     209           0 :                 ip6id_initid(p);
     210             : 
     211             :         /* Skip a random number of ids */
     212           0 :         n = arc4random() & 0x3;
     213           0 :         if (p->ru_counter + n >= p->ru_max)
     214           0 :                 ip6id_initid(p);
     215             : 
     216           0 :         for (i = 0; i <= n; i++) {
     217             :                 /* Linear Congruential Generator */
     218           0 :                 p->ru_x = (u_int32_t)((u_int64_t)p->ru_a * p->ru_x + p->ru_b) % p->ru_m;
     219             :         }
     220             : 
     221           0 :         p->ru_counter += i;
     222             : 
     223           0 :         return (p->ru_seed ^ ip6id_pmod(p->ru_g, p->ru_seed2 + p->ru_x, p->ru_n)) |
     224           0 :             p->ru_msb;
     225             : }
     226             : 
     227             : u_int32_t
     228           0 : ip6_randomflowlabel(void)
     229             : {
     230           0 :         return ip6id_randomid(&randomtab_20) & 0xfffff;
     231             : }
     232             : 

Generated by: LCOV version 1.13