]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/netinet6/ip6_id.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / bsd / netinet6 / ip6_id.c
index 26fffd286dec2c7fe6cb7d44366609e599cae775..24780a44637018418cb1f2a1ae69bed0c49cc09a 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Copyright (c) 2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2019 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
- * 
+ *
  * Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -22,7 +22,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
@@ -53,8 +53,6 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *     $KAME: ip6_id.c,v 1.13 2003/09/16 09:11:19 itojun Exp $
  */
 
 /*-
@@ -90,8 +88,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $OpenBSD: ip_id.c,v 1.6 2002/03/15 18:19:52 millert Exp $
  */
 
 #include <sys/cdefs.h>
 #include <sys/time.h>
 #include <sys/kernel.h>
 #include <sys/random.h>
+#include <sys/protosw.h>
 #include <libkern/libkern.h>
+#include <dev/random/randomdev.h>
 
 #include <net/if.h>
 #include <net/route.h>
 #include <netinet/ip6.h>
 #include <netinet6/ip6_var.h>
 
-#ifndef INT32_MAX
-#define INT32_MAX      0x7fffffffU
-#endif
-
 struct randomtab {
-       const int       ru_bits; /* resulting bits */
-       const long      ru_out; /* Time after wich will be reseeded */
-       const u_int32_t ru_max; /* Uniq cycle, avoid blackjack prediction */
-       const u_int32_t ru_gen; /* Starting generator */
-       const u_int32_t ru_n;   /* ru_n: prime, ru_n - 1: product of pfacts[] */
+       const int       ru_bits; /* resulting bits */
+       const long      ru_out; /* Time after wich will be reseeded */
+       const u_int32_t ru_max; /* Uniq cycle, avoid blackjack prediction */
+       const u_int32_t ru_gen; /* Starting generator */
+       const u_int32_t ru_n;   /* ru_n: prime, ru_n - 1: product of pfacts[] */
        const u_int32_t ru_agen; /* determine ru_a as ru_agen^(2*rand) */
-       const u_int32_t ru_m;   /* ru_m = 2^x*3^y */
-       const u_int32_t pfacts[4];      /* factors of ru_n */
+       const u_int32_t ru_m;   /* ru_m = 2^x*3^y */
+       const u_int32_t pfacts[4];      /* factors of ru_n */
 
        u_int32_t ru_counter;
        u_int32_t ru_msb;
@@ -155,27 +149,23 @@ struct randomtab {
 };
 
 static struct randomtab randomtab_32 = {
-       32,                     /* resulting bits */
-       180,                    /* Time after wich will be reseeded */
-       1000000000,             /* Uniq cycle, avoid blackjack prediction */
-       2,                      /* Starting generator */
-       2147483629,             /* RU_N-1 = 2^2*3^2*59652323 */
-       7,                      /* determine ru_a as RU_AGEN^(2*rand) */
-       1836660096,             /* RU_M = 2^7*3^15 - don't change */
-       { 2, 3, 59652323, 0 },  /* factors of ru_n */
-       0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-static struct randomtab randomtab_20 = {
-       20,                     /* resulting bits */
-       180,                    /* Time after wich will be reseeded */
-       200000,                 /* Uniq cycle, avoid blackjack prediction */
-       2,                      /* Starting generator */
-       524269,                 /* RU_N-1 = 2^2*3^2*14563 */
-       7,                      /* determine ru_a as RU_AGEN^(2*rand) */
-       279936,                 /* RU_M = 2^7*3^7 - don't change */
-       { 2, 3, 14563, 0 },     /* factors of ru_n */
-       0, 0, 0, 0, 0, 0, 0, 0, 0
+       .ru_bits = 32,          /* resulting bits */
+       .ru_out = 180,          /* Time after wich will be reseeded */
+       .ru_max = 1000000000,   /* Uniq cycle, avoid blackjack prediction */
+       .ru_gen = 2,            /* Starting generator */
+       .ru_n = 2147483629,     /* RU_N-1 = 2^2*3^2*59652323 */
+       .ru_agen = 7,           /* determine ru_a as RU_AGEN^(2*rand) */
+       .ru_m = 1836660096,     /* RU_M = 2^7*3^15 - don't change */
+       .pfacts = { 2, 3, 59652323, 0 },        /* factors of ru_n */
+       .ru_counter = 0,
+       .ru_msb = 0,
+       .ru_x = 0,
+       .ru_seed = 0,
+       .ru_seed2 = 0,
+       .ru_a = 0,
+       .ru_b = 0,
+       .ru_g = 0,
+       .ru_reseed = 0
 };
 
 static u_int32_t pmod(u_int32_t, u_int32_t, u_int32_t);
@@ -196,12 +186,13 @@ pmod(u_int32_t gen, u_int32_t expo, u_int32_t mod)
        u = expo;
 
        while (u) {
-               if (u & 1)
+               if (u & 1) {
                        s = (s * t) % mod;
+               }
                u >>= 1;
                t = (t * t) % mod;
        }
-       return (s);
+       return (u_int32_t)s;
 }
 
 /*
@@ -215,26 +206,25 @@ pmod(u_int32_t gen, u_int32_t expo, u_int32_t mod)
 static void
 initid(struct randomtab *p)
 {
+       time_t curtime = (time_t)net_uptime();
        u_int32_t j, i;
        int noprime = 1;
-       struct timeval timenow;
-       
-       getmicrotime(&timenow);
 
-       p->ru_x = random() % p->ru_m;
+       p->ru_x = RandomULong() % p->ru_m;
 
        /* (bits - 1) bits of random seed */
-       p->ru_seed = random() & (~0U >> (32 - p->ru_bits + 1));
-       p->ru_seed2 = random() & (~0U >> (32 - p->ru_bits + 1));
+       p->ru_seed = RandomULong() & (~0U >> (32 - p->ru_bits + 1));
+       p->ru_seed2 = RandomULong() & (~0U >> (32 - p->ru_bits + 1));
 
        /* Determine the LCG we use */
-       p->ru_b = (random() & (~0U >> (32 - p->ru_bits))) | 1;
+       p->ru_b = (RandomULong() & (~0U >> (32 - p->ru_bits))) | 1;
        p->ru_a = pmod(p->ru_agen,
-           (random() & (~0U >> (32 - p->ru_bits))) & (~1U), p->ru_m);
-       while (p->ru_b % 3 == 0)
+           (RandomULong() & (~0U >> (32 - p->ru_bits))) & (~1U), p->ru_m);
+       while (p->ru_b % 3 == 0) {
                p->ru_b += 2;
+       }
 
-       j = random() % p->ru_n;
+       j = RandomULong() % p->ru_n;
 
        /*
         * Do a fast gcd(j, RU_N - 1), so we can find a j with
@@ -242,63 +232,64 @@ initid(struct randomtab *p)
         * RU_GEN^j mod RU_N
         */
        while (noprime) {
-               for (i = 0; p->pfacts[i] > 0; i++)
-                       if (j % p->pfacts[i] == 0)
+               for (i = 0; p->pfacts[i] > 0; i++) {
+                       if (j % p->pfacts[i] == 0) {
                                break;
+                       }
+               }
 
-               if (p->pfacts[i] == 0)
+               if (p->pfacts[i] == 0) {
                        noprime = 0;
-               else
+               } else {
                        j = (j + 1) % p->ru_n;
+               }
        }
 
        p->ru_g = pmod(p->ru_gen, j, p->ru_n);
        p->ru_counter = 0;
 
-       p->ru_reseed = timenow.tv_sec + p->ru_out;
+       p->ru_reseed = curtime + p->ru_out;
        p->ru_msb = p->ru_msb ? 0 : (1U << (p->ru_bits - 1));
 }
 
 static u_int32_t
 randomid(struct randomtab *p)
 {
+       time_t curtime = (time_t)net_uptime();
        int i, n;
        u_int32_t tmp;
-       struct timeval timenow;
 
-       getmicrotime(&timenow);
-
-       if (p->ru_counter >= p->ru_max || timenow.tv_sec > p->ru_reseed)
+       if (p->ru_counter >= p->ru_max || curtime > p->ru_reseed) {
                initid(p);
+       }
 
-       tmp = random();
+       tmp = RandomULong();
 
        /* Skip a random number of ids */
        n = tmp & 0x3; tmp = tmp >> 2;
-       if (p->ru_counter + n >= p->ru_max)
+       if (p->ru_counter + n >= p->ru_max) {
                initid(p);
+       }
 
        for (i = 0; i <= n; i++) {
                /* Linear Congruential Generator */
-               p->ru_x = (u_int32_t)((u_int64_t)p->ru_a * p->ru_x + p->ru_b) % p->ru_m;
+               p->ru_x = ((u_int64_t)p->ru_a * p->ru_x + p->ru_b) % p->ru_m;
        }
 
        p->ru_counter += i;
 
        return (p->ru_seed ^ pmod(p->ru_g, p->ru_seed2 ^ p->ru_x, p->ru_n)) |
-           p->ru_msb;
+              p->ru_msb;
 }
 
 u_int32_t
 ip6_randomid(void)
 {
-
        return randomid(&randomtab_32);
 }
 
 u_int32_t
 ip6_randomflowlabel(void)
 {
-
-       return randomid(&randomtab_20) & 0xfffff;
+       return RandomULong() & IPV6_FLOWLABEL_MASK;
 }