Commit 7cd4767e696123cdb7447fbd7c281eb8c610c8e4

Authored by Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net:
  net: Compute protocol sequence numbers and fragment IDs using MD5.
  crypto: Move md5_transform to lib/md5.c

Showing 18 changed files Side-by-side Diff

... ... @@ -21,98 +21,8 @@
21 21 #include <linux/module.h>
22 22 #include <linux/string.h>
23 23 #include <linux/types.h>
  24 +#include <linux/cryptohash.h>
24 25 #include <asm/byteorder.h>
25   -
26   -#define F1(x, y, z) (z ^ (x & (y ^ z)))
27   -#define F2(x, y, z) F1(z, x, y)
28   -#define F3(x, y, z) (x ^ y ^ z)
29   -#define F4(x, y, z) (y ^ (x | ~z))
30   -
31   -#define MD5STEP(f, w, x, y, z, in, s) \
32   - (w += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x)
33   -
34   -static void md5_transform(u32 *hash, u32 const *in)
35   -{
36   - u32 a, b, c, d;
37   -
38   - a = hash[0];
39   - b = hash[1];
40   - c = hash[2];
41   - d = hash[3];
42   -
43   - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
44   - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
45   - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
46   - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
47   - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
48   - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
49   - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
50   - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
51   - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
52   - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
53   - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
54   - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
55   - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
56   - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
57   - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
58   - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
59   -
60   - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
61   - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
62   - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
63   - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
64   - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
65   - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
66   - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
67   - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
68   - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
69   - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
70   - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
71   - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
72   - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
73   - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
74   - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
75   - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
76   -
77   - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
78   - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
79   - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
80   - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
81   - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
82   - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
83   - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
84   - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
85   - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
86   - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
87   - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
88   - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
89   - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
90   - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
91   - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
92   - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
93   -
94   - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
95   - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
96   - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
97   - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
98   - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
99   - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
100   - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
101   - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
102   - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
103   - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
104   - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
105   - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
106   - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
107   - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
108   - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
109   - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
110   -
111   - hash[0] += a;
112   - hash[1] += b;
113   - hash[2] += c;
114   - hash[3] += d;
115   -}
116 26  
117 27 /* XXX: this stuff can be optimized */
118 28 static inline void le32_to_cpu_array(u32 *buf, unsigned int words)
drivers/char/random.c
... ... @@ -1300,363 +1300,30 @@
1300 1300 };
1301 1301 #endif /* CONFIG_SYSCTL */
1302 1302  
1303   -/********************************************************************
1304   - *
1305   - * Random functions for networking
1306   - *
1307   - ********************************************************************/
  1303 +static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned;
1308 1304  
1309   -/*
1310   - * TCP initial sequence number picking. This uses the random number
1311   - * generator to pick an initial secret value. This value is hashed
1312   - * along with the TCP endpoint information to provide a unique
1313   - * starting point for each pair of TCP endpoints. This defeats
1314   - * attacks which rely on guessing the initial TCP sequence number.
1315   - * This algorithm was suggested by Steve Bellovin.
1316   - *
1317   - * Using a very strong hash was taking an appreciable amount of the total
1318   - * TCP connection establishment time, so this is a weaker hash,
1319   - * compensated for by changing the secret periodically.
1320   - */
1321   -
1322   -/* F, G and H are basic MD4 functions: selection, majority, parity */
1323   -#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
1324   -#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
1325   -#define H(x, y, z) ((x) ^ (y) ^ (z))
1326   -
1327   -/*
1328   - * The generic round function. The application is so specific that
1329   - * we don't bother protecting all the arguments with parens, as is generally
1330   - * good macro practice, in favor of extra legibility.
1331   - * Rotation is separate from addition to prevent recomputation
1332   - */
1333   -#define ROUND(f, a, b, c, d, x, s) \
1334   - (a += f(b, c, d) + x, a = (a << s) | (a >> (32 - s)))
1335   -#define K1 0
1336   -#define K2 013240474631UL
1337   -#define K3 015666365641UL
1338   -
1339   -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1340   -
1341   -static __u32 twothirdsMD4Transform(__u32 const buf[4], __u32 const in[12])
  1305 +static int __init random_int_secret_init(void)
1342 1306 {
1343   - __u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
1344   -
1345   - /* Round 1 */
1346   - ROUND(F, a, b, c, d, in[ 0] + K1, 3);
1347   - ROUND(F, d, a, b, c, in[ 1] + K1, 7);
1348   - ROUND(F, c, d, a, b, in[ 2] + K1, 11);
1349   - ROUND(F, b, c, d, a, in[ 3] + K1, 19);
1350   - ROUND(F, a, b, c, d, in[ 4] + K1, 3);
1351   - ROUND(F, d, a, b, c, in[ 5] + K1, 7);
1352   - ROUND(F, c, d, a, b, in[ 6] + K1, 11);
1353   - ROUND(F, b, c, d, a, in[ 7] + K1, 19);
1354   - ROUND(F, a, b, c, d, in[ 8] + K1, 3);
1355   - ROUND(F, d, a, b, c, in[ 9] + K1, 7);
1356   - ROUND(F, c, d, a, b, in[10] + K1, 11);
1357   - ROUND(F, b, c, d, a, in[11] + K1, 19);
1358   -
1359   - /* Round 2 */
1360   - ROUND(G, a, b, c, d, in[ 1] + K2, 3);
1361   - ROUND(G, d, a, b, c, in[ 3] + K2, 5);
1362   - ROUND(G, c, d, a, b, in[ 5] + K2, 9);
1363   - ROUND(G, b, c, d, a, in[ 7] + K2, 13);
1364   - ROUND(G, a, b, c, d, in[ 9] + K2, 3);
1365   - ROUND(G, d, a, b, c, in[11] + K2, 5);
1366   - ROUND(G, c, d, a, b, in[ 0] + K2, 9);
1367   - ROUND(G, b, c, d, a, in[ 2] + K2, 13);
1368   - ROUND(G, a, b, c, d, in[ 4] + K2, 3);
1369   - ROUND(G, d, a, b, c, in[ 6] + K2, 5);
1370   - ROUND(G, c, d, a, b, in[ 8] + K2, 9);
1371   - ROUND(G, b, c, d, a, in[10] + K2, 13);
1372   -
1373   - /* Round 3 */
1374   - ROUND(H, a, b, c, d, in[ 3] + K3, 3);
1375   - ROUND(H, d, a, b, c, in[ 7] + K3, 9);
1376   - ROUND(H, c, d, a, b, in[11] + K3, 11);
1377   - ROUND(H, b, c, d, a, in[ 2] + K3, 15);
1378   - ROUND(H, a, b, c, d, in[ 6] + K3, 3);
1379   - ROUND(H, d, a, b, c, in[10] + K3, 9);
1380   - ROUND(H, c, d, a, b, in[ 1] + K3, 11);
1381   - ROUND(H, b, c, d, a, in[ 5] + K3, 15);
1382   - ROUND(H, a, b, c, d, in[ 9] + K3, 3);
1383   - ROUND(H, d, a, b, c, in[ 0] + K3, 9);
1384   - ROUND(H, c, d, a, b, in[ 4] + K3, 11);
1385   - ROUND(H, b, c, d, a, in[ 8] + K3, 15);
1386   -
1387   - return buf[1] + b; /* "most hashed" word */
1388   - /* Alternative: return sum of all words? */
1389   -}
1390   -#endif
1391   -
1392   -#undef ROUND
1393   -#undef F
1394   -#undef G
1395   -#undef H
1396   -#undef K1
1397   -#undef K2
1398   -#undef K3
1399   -
1400   -/* This should not be decreased so low that ISNs wrap too fast. */
1401   -#define REKEY_INTERVAL (300 * HZ)
1402   -/*
1403   - * Bit layout of the tcp sequence numbers (before adding current time):
1404   - * bit 24-31: increased after every key exchange
1405   - * bit 0-23: hash(source,dest)
1406   - *
1407   - * The implementation is similar to the algorithm described
1408   - * in the Appendix of RFC 1185, except that
1409   - * - it uses a 1 MHz clock instead of a 250 kHz clock
1410   - * - it performs a rekey every 5 minutes, which is equivalent
1411   - * to a (source,dest) tulple dependent forward jump of the
1412   - * clock by 0..2^(HASH_BITS+1)
1413   - *
1414   - * Thus the average ISN wraparound time is 68 minutes instead of
1415   - * 4.55 hours.
1416   - *
1417   - * SMP cleanup and lock avoidance with poor man's RCU.
1418   - * Manfred Spraul <manfred@colorfullife.com>
1419   - *
1420   - */
1421   -#define COUNT_BITS 8
1422   -#define COUNT_MASK ((1 << COUNT_BITS) - 1)
1423   -#define HASH_BITS 24
1424   -#define HASH_MASK ((1 << HASH_BITS) - 1)
1425   -
1426   -static struct keydata {
1427   - __u32 count; /* already shifted to the final position */
1428   - __u32 secret[12];
1429   -} ____cacheline_aligned ip_keydata[2];
1430   -
1431   -static unsigned int ip_cnt;
1432   -
1433   -static void rekey_seq_generator(struct work_struct *work);
1434   -
1435   -static DECLARE_DELAYED_WORK(rekey_work, rekey_seq_generator);
1436   -
1437   -/*
1438   - * Lock avoidance:
1439   - * The ISN generation runs lockless - it's just a hash over random data.
1440   - * State changes happen every 5 minutes when the random key is replaced.
1441   - * Synchronization is performed by having two copies of the hash function
1442   - * state and rekey_seq_generator always updates the inactive copy.
1443   - * The copy is then activated by updating ip_cnt.
1444   - * The implementation breaks down if someone blocks the thread
1445   - * that processes SYN requests for more than 5 minutes. Should never
1446   - * happen, and even if that happens only a not perfectly compliant
1447   - * ISN is generated, nothing fatal.
1448   - */
1449   -static void rekey_seq_generator(struct work_struct *work)
1450   -{
1451   - struct keydata *keyptr = &ip_keydata[1 ^ (ip_cnt & 1)];
1452   -
1453   - get_random_bytes(keyptr->secret, sizeof(keyptr->secret));
1454   - keyptr->count = (ip_cnt & COUNT_MASK) << HASH_BITS;
1455   - smp_wmb();
1456   - ip_cnt++;
1457   - schedule_delayed_work(&rekey_work,
1458   - round_jiffies_relative(REKEY_INTERVAL));
1459   -}
1460   -
1461   -static inline struct keydata *get_keyptr(void)
1462   -{
1463   - struct keydata *keyptr = &ip_keydata[ip_cnt & 1];
1464   -
1465   - smp_rmb();
1466   -
1467   - return keyptr;
1468   -}
1469   -
1470   -static __init int seqgen_init(void)
1471   -{
1472   - rekey_seq_generator(NULL);
  1307 + get_random_bytes(random_int_secret, sizeof(random_int_secret));
1473 1308 return 0;
1474 1309 }
1475   -late_initcall(seqgen_init);
  1310 +late_initcall(random_int_secret_init);
1476 1311  
1477   -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1478   -__u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr,
1479   - __be16 sport, __be16 dport)
1480   -{
1481   - __u32 seq;
1482   - __u32 hash[12];
1483   - struct keydata *keyptr = get_keyptr();
1484   -
1485   - /* The procedure is the same as for IPv4, but addresses are longer.
1486   - * Thus we must use twothirdsMD4Transform.
1487   - */
1488   -
1489   - memcpy(hash, saddr, 16);
1490   - hash[4] = ((__force u16)sport << 16) + (__force u16)dport;
1491   - memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7);
1492   -
1493   - seq = twothirdsMD4Transform((const __u32 *)daddr, hash) & HASH_MASK;
1494   - seq += keyptr->count;
1495   -
1496   - seq += ktime_to_ns(ktime_get_real());
1497   -
1498   - return seq;
1499   -}
1500   -EXPORT_SYMBOL(secure_tcpv6_sequence_number);
1501   -#endif
1502   -
1503   -/* The code below is shamelessly stolen from secure_tcp_sequence_number().
1504   - * All blames to Andrey V. Savochkin <saw@msu.ru>.
1505   - */
1506   -__u32 secure_ip_id(__be32 daddr)
1507   -{
1508   - struct keydata *keyptr;
1509   - __u32 hash[4];
1510   -
1511   - keyptr = get_keyptr();
1512   -
1513   - /*
1514   - * Pick a unique starting offset for each IP destination.
1515   - * The dest ip address is placed in the starting vector,
1516   - * which is then hashed with random data.
1517   - */
1518   - hash[0] = (__force __u32)daddr;
1519   - hash[1] = keyptr->secret[9];
1520   - hash[2] = keyptr->secret[10];
1521   - hash[3] = keyptr->secret[11];
1522   -
1523   - return half_md4_transform(hash, keyptr->secret);
1524   -}
1525   -
1526   -__u32 secure_ipv6_id(const __be32 daddr[4])
1527   -{
1528   - const struct keydata *keyptr;
1529   - __u32 hash[4];
1530   -
1531   - keyptr = get_keyptr();
1532   -
1533   - hash[0] = (__force __u32)daddr[0];
1534   - hash[1] = (__force __u32)daddr[1];
1535   - hash[2] = (__force __u32)daddr[2];
1536   - hash[3] = (__force __u32)daddr[3];
1537   -
1538   - return half_md4_transform(hash, keyptr->secret);
1539   -}
1540   -
1541   -#ifdef CONFIG_INET
1542   -
1543   -__u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
1544   - __be16 sport, __be16 dport)
1545   -{
1546   - __u32 seq;
1547   - __u32 hash[4];
1548   - struct keydata *keyptr = get_keyptr();
1549   -
1550   - /*
1551   - * Pick a unique starting offset for each TCP connection endpoints
1552   - * (saddr, daddr, sport, dport).
1553   - * Note that the words are placed into the starting vector, which is
1554   - * then mixed with a partial MD4 over random data.
1555   - */
1556   - hash[0] = (__force u32)saddr;
1557   - hash[1] = (__force u32)daddr;
1558   - hash[2] = ((__force u16)sport << 16) + (__force u16)dport;
1559   - hash[3] = keyptr->secret[11];
1560   -
1561   - seq = half_md4_transform(hash, keyptr->secret) & HASH_MASK;
1562   - seq += keyptr->count;
1563   - /*
1564   - * As close as possible to RFC 793, which
1565   - * suggests using a 250 kHz clock.
1566   - * Further reading shows this assumes 2 Mb/s networks.
1567   - * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate.
1568   - * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but
1569   - * we also need to limit the resolution so that the u32 seq
1570   - * overlaps less than one time per MSL (2 minutes).
1571   - * Choosing a clock of 64 ns period is OK. (period of 274 s)
1572   - */
1573   - seq += ktime_to_ns(ktime_get_real()) >> 6;
1574   -
1575   - return seq;
1576   -}
1577   -
1578   -/* Generate secure starting point for ephemeral IPV4 transport port search */
1579   -u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
1580   -{
1581   - struct keydata *keyptr = get_keyptr();
1582   - u32 hash[4];
1583   -
1584   - /*
1585   - * Pick a unique starting offset for each ephemeral port search
1586   - * (saddr, daddr, dport) and 48bits of random data.
1587   - */
1588   - hash[0] = (__force u32)saddr;
1589   - hash[1] = (__force u32)daddr;
1590   - hash[2] = (__force u32)dport ^ keyptr->secret[10];
1591   - hash[3] = keyptr->secret[11];
1592   -
1593   - return half_md4_transform(hash, keyptr->secret);
1594   -}
1595   -EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral);
1596   -
1597   -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1598   -u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
1599   - __be16 dport)
1600   -{
1601   - struct keydata *keyptr = get_keyptr();
1602   - u32 hash[12];
1603   -
1604   - memcpy(hash, saddr, 16);
1605   - hash[4] = (__force u32)dport;
1606   - memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7);
1607   -
1608   - return twothirdsMD4Transform((const __u32 *)daddr, hash);
1609   -}
1610   -#endif
1611   -
1612   -#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
1613   -/* Similar to secure_tcp_sequence_number but generate a 48 bit value
1614   - * bit's 32-47 increase every key exchange
1615   - * 0-31 hash(source, dest)
1616   - */
1617   -u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr,
1618   - __be16 sport, __be16 dport)
1619   -{
1620   - u64 seq;
1621   - __u32 hash[4];
1622   - struct keydata *keyptr = get_keyptr();
1623   -
1624   - hash[0] = (__force u32)saddr;
1625   - hash[1] = (__force u32)daddr;
1626   - hash[2] = ((__force u16)sport << 16) + (__force u16)dport;
1627   - hash[3] = keyptr->secret[11];
1628   -
1629   - seq = half_md4_transform(hash, keyptr->secret);
1630   - seq |= ((u64)keyptr->count) << (32 - HASH_BITS);
1631   -
1632   - seq += ktime_to_ns(ktime_get_real());
1633   - seq &= (1ull << 48) - 1;
1634   -
1635   - return seq;
1636   -}
1637   -EXPORT_SYMBOL(secure_dccp_sequence_number);
1638   -#endif
1639   -
1640   -#endif /* CONFIG_INET */
1641   -
1642   -
1643 1312 /*
1644 1313 * Get a random word for internal kernel use only. Similar to urandom but
1645 1314 * with the goal of minimal entropy pool depletion. As a result, the random
1646 1315 * value is not cryptographically secure but for several uses the cost of
1647 1316 * depleting entropy is too high
1648 1317 */
1649   -DEFINE_PER_CPU(__u32 [4], get_random_int_hash);
  1318 +DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash);
1650 1319 unsigned int get_random_int(void)
1651 1320 {
1652   - struct keydata *keyptr;
1653 1321 __u32 *hash = get_cpu_var(get_random_int_hash);
1654   - int ret;
  1322 + unsigned int ret;
1655 1323  
1656   - keyptr = get_keyptr();
1657 1324 hash[0] += current->pid + jiffies + get_cycles();
1658   -
1659   - ret = half_md4_transform(hash, keyptr->secret);
  1325 + md5_transform(hash, random_int_secret);
  1326 + ret = hash[0];
1660 1327 put_cpu_var(get_random_int_hash);
1661 1328  
1662 1329 return ret;
include/linux/cryptohash.h
... ... @@ -8,6 +8,11 @@
8 8 void sha_init(__u32 *buf);
9 9 void sha_transform(__u32 *digest, const char *data, __u32 *W);
10 10  
  11 +#define MD5_DIGEST_WORDS 4
  12 +#define MD5_MESSAGE_BYTES 64
  13 +
  14 +void md5_transform(__u32 *hash, __u32 const *in);
  15 +
11 16 __u32 half_md4_transform(__u32 buf[4], __u32 const in[8]);
12 17  
13 18 #endif
include/linux/random.h
... ... @@ -57,18 +57,6 @@
57 57 extern void get_random_bytes(void *buf, int nbytes);
58 58 void generate_random_uuid(unsigned char uuid_out[16]);
59 59  
60   -extern __u32 secure_ip_id(__be32 daddr);
61   -extern __u32 secure_ipv6_id(const __be32 daddr[4]);
62   -extern u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
63   -extern u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
64   - __be16 dport);
65   -extern __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
66   - __be16 sport, __be16 dport);
67   -extern __u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr,
68   - __be16 sport, __be16 dport);
69   -extern u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr,
70   - __be16 sport, __be16 dport);
71   -
72 60 #ifndef MODULE
73 61 extern const struct file_operations random_fops, urandom_fops;
74 62 #endif
include/net/secure_seq.h
  1 +#ifndef _NET_SECURE_SEQ
  2 +#define _NET_SECURE_SEQ
  3 +
  4 +#include <linux/types.h>
  5 +
  6 +extern __u32 secure_ip_id(__be32 daddr);
  7 +extern __u32 secure_ipv6_id(const __be32 daddr[4]);
  8 +extern u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
  9 +extern u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
  10 + __be16 dport);
  11 +extern __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
  12 + __be16 sport, __be16 dport);
  13 +extern __u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr,
  14 + __be16 sport, __be16 dport);
  15 +extern u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr,
  16 + __be16 sport, __be16 dport);
  17 +extern u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr,
  18 + __be16 sport, __be16 dport);
  19 +
  20 +#endif /* _NET_SECURE_SEQ */
... ... @@ -10,7 +10,7 @@
10 10 lib-y := ctype.o string.o vsprintf.o cmdline.o \
11 11 rbtree.o radix-tree.o dump_stack.o timerqueue.o\
12 12 idr.o int_sqrt.o extable.o prio_tree.o \
13   - sha1.o irq_regs.o reciprocal_div.o argv_split.o \
  13 + sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \
14 14 proportions.o prio_heap.o ratelimit.o show_mem.o \
15 15 is_single_threaded.o plist.o decompress.o find_next_bit.o
16 16  
  1 +#include <linux/kernel.h>
  2 +#include <linux/module.h>
  3 +#include <linux/cryptohash.h>
  4 +
  5 +#define F1(x, y, z) (z ^ (x & (y ^ z)))
  6 +#define F2(x, y, z) F1(z, x, y)
  7 +#define F3(x, y, z) (x ^ y ^ z)
  8 +#define F4(x, y, z) (y ^ (x | ~z))
  9 +
  10 +#define MD5STEP(f, w, x, y, z, in, s) \
  11 + (w += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x)
  12 +
  13 +void md5_transform(__u32 *hash, __u32 const *in)
  14 +{
  15 + u32 a, b, c, d;
  16 +
  17 + a = hash[0];
  18 + b = hash[1];
  19 + c = hash[2];
  20 + d = hash[3];
  21 +
  22 + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
  23 + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
  24 + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
  25 + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
  26 + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
  27 + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
  28 + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
  29 + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
  30 + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
  31 + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
  32 + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
  33 + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
  34 + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
  35 + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
  36 + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
  37 + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
  38 +
  39 + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
  40 + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
  41 + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
  42 + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
  43 + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
  44 + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
  45 + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
  46 + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
  47 + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
  48 + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
  49 + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
  50 + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
  51 + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
  52 + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
  53 + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
  54 + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
  55 +
  56 + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
  57 + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
  58 + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
  59 + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
  60 + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
  61 + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
  62 + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
  63 + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
  64 + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
  65 + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
  66 + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
  67 + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
  68 + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
  69 + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
  70 + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
  71 + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
  72 +
  73 + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
  74 + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
  75 + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
  76 + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
  77 + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
  78 + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
  79 + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
  80 + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
  81 + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
  82 + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
  83 + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
  84 + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
  85 + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
  86 + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
  87 + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
  88 + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
  89 +
  90 + hash[0] += a;
  91 + hash[1] += b;
  92 + hash[2] += c;
  93 + hash[3] += d;
  94 +}
  95 +EXPORT_SYMBOL(md5_transform);
... ... @@ -3,7 +3,7 @@
3 3 #
4 4  
5 5 obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \
6   - gen_stats.o gen_estimator.o net_namespace.o
  6 + gen_stats.o gen_estimator.o net_namespace.o secure_seq.o
7 7  
8 8 obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
9 9  
net/core/secure_seq.c
  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
... ... @@ -26,6 +26,7 @@
26 26 #include <net/timewait_sock.h>
27 27 #include <net/tcp_states.h>
28 28 #include <net/xfrm.h>
  29 +#include <net/secure_seq.h>
29 30  
30 31 #include "ackvec.h"
31 32 #include "ccid.h"
... ... @@ -29,6 +29,7 @@
29 29 #include <net/transp_v6.h>
30 30 #include <net/ip6_checksum.h>
31 31 #include <net/xfrm.h>
  32 +#include <net/secure_seq.h>
32 33  
33 34 #include "dccp.h"
34 35 #include "ipv6.h"
... ... @@ -69,13 +70,7 @@
69 70 dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr);
70 71 }
71 72  
72   -static inline __u32 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr,
73   - __be16 sport, __be16 dport )
74   -{
75   - return secure_tcpv6_sequence_number(saddr, daddr, sport, dport);
76   -}
77   -
78   -static inline __u32 dccp_v6_init_sequence(struct sk_buff *skb)
  73 +static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb)
79 74 {
80 75 return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32,
81 76 ipv6_hdr(skb)->saddr.s6_addr32,
net/ipv4/inet_hashtables.c
... ... @@ -21,6 +21,7 @@
21 21  
22 22 #include <net/inet_connection_sock.h>
23 23 #include <net/inet_hashtables.h>
  24 +#include <net/secure_seq.h>
24 25 #include <net/ip.h>
25 26  
26 27 /*
... ... @@ -19,6 +19,7 @@
19 19 #include <linux/net.h>
20 20 #include <net/ip.h>
21 21 #include <net/inetpeer.h>
  22 +#include <net/secure_seq.h>
22 23  
23 24 /*
24 25 * Theory of operations.
net/ipv4/netfilter/nf_nat_proto_common.c
... ... @@ -12,6 +12,7 @@
12 12 #include <linux/ip.h>
13 13  
14 14 #include <linux/netfilter.h>
  15 +#include <net/secure_seq.h>
15 16 #include <net/netfilter/nf_nat.h>
16 17 #include <net/netfilter/nf_nat_core.h>
17 18 #include <net/netfilter/nf_nat_rule.h>
... ... @@ -109,6 +109,7 @@
109 109 #include <linux/sysctl.h>
110 110 #endif
111 111 #include <net/atmclip.h>
  112 +#include <net/secure_seq.h>
112 113  
113 114 #define RT_FL_TOS(oldflp4) \
114 115 ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK)))
... ... @@ -72,6 +72,7 @@
72 72 #include <net/timewait_sock.h>
73 73 #include <net/xfrm.h>
74 74 #include <net/netdma.h>
  75 +#include <net/secure_seq.h>
75 76  
76 77 #include <linux/inet.h>
77 78 #include <linux/ipv6.h>
net/ipv6/inet6_hashtables.c
... ... @@ -20,6 +20,7 @@
20 20 #include <net/inet_connection_sock.h>
21 21 #include <net/inet_hashtables.h>
22 22 #include <net/inet6_hashtables.h>
  23 +#include <net/secure_seq.h>
23 24 #include <net/ip.h>
24 25  
25 26 int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw)
... ... @@ -61,6 +61,7 @@
61 61 #include <net/timewait_sock.h>
62 62 #include <net/netdma.h>
63 63 #include <net/inet_common.h>
  64 +#include <net/secure_seq.h>
64 65  
65 66 #include <asm/uaccess.h>
66 67