~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/core/secure_seq.c

Version: ~ [ linux-5.2-rc1 ] ~ [ linux-5.1.2 ] ~ [ linux-5.0.16 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.43 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.119 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.176 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.179 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.139 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.67 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #include <linux/kernel.h>
  2 #include <linux/init.h>
  3 #include <linux/cryptohash.h>
  4 #include <linux/module.h>
  5 #include <linux/cache.h>
  6 #include <linux/random.h>
  7 #include <linux/hrtimer.h>
  8 #include <linux/ktime.h>
  9 #include <linux/string.h>
 10 
 11 #include <net/secure_seq.h>
 12 
 13 static u32 net_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned;
 14 
 15 static int __init net_secret_init(void)
 16 {
 17         get_random_bytes(net_secret, sizeof(net_secret));
 18         return 0;
 19 }
 20 late_initcall(net_secret_init);
 21 
 22 static u32 seq_scale(u32 seq)
 23 {
 24         /*
 25          *      As close as possible to RFC 793, which
 26          *      suggests using a 250 kHz clock.
 27          *      Further reading shows this assumes 2 Mb/s networks.
 28          *      For 10 Mb/s Ethernet, a 1 MHz clock is appropriate.
 29          *      For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but
 30          *      we also need to limit the resolution so that the u32 seq
 31          *      overlaps less than one time per MSL (2 minutes).
 32          *      Choosing a clock of 64 ns period is OK. (period of 274 s)
 33          */
 34         return seq + (ktime_to_ns(ktime_get_real()) >> 6);
 35 }
 36 
 37 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 38 __u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr,
 39                                    __be16 sport, __be16 dport)
 40 {
 41         u32 secret[MD5_MESSAGE_BYTES / 4];
 42         u32 hash[MD5_DIGEST_WORDS];
 43         u32 i;
 44 
 45         memcpy(hash, saddr, 16);
 46         for (i = 0; i < 4; i++)
 47                 secret[i] = net_secret[i] + daddr[i];
 48         secret[4] = net_secret[4] +
 49                 (((__force u16)sport << 16) + (__force u16)dport);
 50         for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++)
 51                 secret[i] = net_secret[i];
 52 
 53         md5_transform(hash, secret);
 54 
 55         return seq_scale(hash[0]);
 56 }
 57 EXPORT_SYMBOL(secure_tcpv6_sequence_number);
 58 
 59 u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
 60                                __be16 dport)
 61 {
 62         u32 secret[MD5_MESSAGE_BYTES / 4];
 63         u32 hash[MD5_DIGEST_WORDS];
 64         u32 i;
 65 
 66         memcpy(hash, saddr, 16);
 67         for (i = 0; i < 4; i++)
 68                 secret[i] = net_secret[i] + (__force u32) daddr[i];
 69         secret[4] = net_secret[4] + (__force u32)dport;
 70         for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++)
 71                 secret[i] = net_secret[i];
 72 
 73         md5_transform(hash, secret);
 74 
 75         return hash[0];
 76 }
 77 #endif
 78 
 79 #ifdef CONFIG_INET
 80 __u32 secure_ip_id(__be32 daddr)
 81 {
 82         u32 hash[MD5_DIGEST_WORDS];
 83 
 84         hash[0] = (__force __u32) daddr;
 85         hash[1] = net_secret[13];
 86         hash[2] = net_secret[14];
 87         hash[3] = net_secret[15];
 88 
 89         md5_transform(hash, net_secret);
 90 
 91         return hash[0];
 92 }
 93 
 94 __u32 secure_ipv6_id(const __be32 daddr[4])
 95 {
 96         __u32 hash[4];
 97 
 98         memcpy(hash, daddr, 16);
 99         md5_transform(hash, net_secret);
100 
101         return hash[0];
102 }
103 
104 __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
105                                  __be16 sport, __be16 dport)
106 {
107         u32 hash[MD5_DIGEST_WORDS];
108 
109         hash[0] = (__force u32)saddr;
110         hash[1] = (__force u32)daddr;
111         hash[2] = ((__force u16)sport << 16) + (__force u16)dport;
112         hash[3] = net_secret[15];
113 
114         md5_transform(hash, net_secret);
115 
116         return seq_scale(hash[0]);
117 }
118 
119 u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
120 {
121         u32 hash[MD5_DIGEST_WORDS];
122 
123         hash[0] = (__force u32)saddr;
124         hash[1] = (__force u32)daddr;
125         hash[2] = (__force u32)dport ^ net_secret[14];
126         hash[3] = net_secret[15];
127 
128         md5_transform(hash, net_secret);
129 
130         return hash[0];
131 }
132 EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral);
133 #endif
134 
135 #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
136 u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr,
137                                 __be16 sport, __be16 dport)
138 {
139         u32 hash[MD5_DIGEST_WORDS];
140         u64 seq;
141 
142         hash[0] = (__force u32)saddr;
143         hash[1] = (__force u32)daddr;
144         hash[2] = ((__force u16)sport << 16) + (__force u16)dport;
145         hash[3] = net_secret[15];
146 
147         md5_transform(hash, net_secret);
148 
149         seq = hash[0] | (((u64)hash[1]) << 32);
150         seq += ktime_to_ns(ktime_get_real());
151         seq &= (1ull << 48) - 1;
152 
153         return seq;
154 }
155 EXPORT_SYMBOL(secure_dccp_sequence_number);
156 
157 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
158 u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr,
159                                   __be16 sport, __be16 dport)
160 {
161         u32 secret[MD5_MESSAGE_BYTES / 4];
162         u32 hash[MD5_DIGEST_WORDS];
163         u64 seq;
164         u32 i;
165 
166         memcpy(hash, saddr, 16);
167         for (i = 0; i < 4; i++)
168                 secret[i] = net_secret[i] + daddr[i];
169         secret[4] = net_secret[4] +
170                 (((__force u16)sport << 16) + (__force u16)dport);
171         for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++)
172                 secret[i] = net_secret[i];
173 
174         md5_transform(hash, secret);
175 
176         seq = hash[0] | (((u64)hash[1]) << 32);
177         seq += ktime_to_ns(ktime_get_real());
178         seq &= (1ull << 48) - 1;
179 
180         return seq;
181 }
182 EXPORT_SYMBOL(secure_dccpv6_sequence_number);
183 #endif
184 #endif
185 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp