diff options
| author | David S. Miller <davem@davemloft.net> | 2011-08-03 23:50:44 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-08-15 21:31:35 -0400 |
| commit | e997d47bff5a467262ef224b4cf8cbba2d3eceea (patch) | |
| tree | 6560c0ac8f2b19a4b7f40db6cc22a9857fe4f1a3 /drivers/char | |
| parent | 2468b895fc7dcbc436cb02f0707ab8d7cb2f0aa7 (diff) | |
net: Compute protocol sequence numbers and fragment IDs using MD5.
Computers have become a lot faster since we compromised on the
partial MD4 hash which we use currently for performance reasons.
MD5 is a much safer choice, and is inline with both RFC1948 and
other ISS generators (OpenBSD, Solaris, etc.)
Furthermore, only having 24-bits of the sequence number be truly
unpredictable is a very serious limitation. So the periodic
regeneration and 8-bit counter have been removed. We compute and
use a full 32-bit sequence number.
For ipv6, DCCP was found to use a 32-bit truncated initial sequence
number (it needs 43-bits) and that is fixed here as well.
Reported-by: Dan Kaminsky <dan@doxpara.com>
Tested-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/char')
| -rw-r--r-- | drivers/char/random.c | 334 |
1 files changed, 8 insertions, 326 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c index d4ddeba5668..c35a785005b 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
| @@ -1300,330 +1300,14 @@ ctl_table random_table[] = { | |||
| 1300 | }; | 1300 | }; |
| 1301 | #endif /* CONFIG_SYSCTL */ | 1301 | #endif /* CONFIG_SYSCTL */ |
| 1302 | 1302 | ||
| 1303 | /******************************************************************** | 1303 | static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; |
| 1304 | * | ||
| 1305 | * Random functions for networking | ||
| 1306 | * | ||
| 1307 | ********************************************************************/ | ||
| 1308 | |||
| 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 | 1304 | ||
| 1339 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 1305 | static int __init random_int_secret_init(void) |
| 1340 | |||
| 1341 | static __u32 twothirdsMD4Transform(__u32 const buf[4], __u32 const in[12]) | ||
| 1342 | { | 1306 | { |
| 1343 | __u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; | 1307 | get_random_bytes(random_int_secret, sizeof(random_int_secret)); |
| 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); | ||
| 1473 | return 0; | 1308 | return 0; |
| 1474 | } | 1309 | } |
| 1475 | late_initcall(seqgen_init); | 1310 | late_initcall(random_int_secret_init); |
| 1476 | |||
| 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 | #ifdef CONFIG_INET | ||
| 1527 | |||
| 1528 | __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, | ||
| 1529 | __be16 sport, __be16 dport) | ||
| 1530 | { | ||
| 1531 | __u32 seq; | ||
| 1532 | __u32 hash[4]; | ||
| 1533 | struct keydata *keyptr = get_keyptr(); | ||
| 1534 | |||
| 1535 | /* | ||
| 1536 | * Pick a unique starting offset for each TCP connection endpoints | ||
| 1537 | * (saddr, daddr, sport, dport). | ||
| 1538 | * Note that the words are placed into the starting vector, which is | ||
| 1539 | * then mixed with a partial MD4 over random data. | ||
| 1540 | */ | ||
| 1541 | hash[0] = (__force u32)saddr; | ||
| 1542 | hash[1] = (__force u32)daddr; | ||
| 1543 | hash[2] = ((__force u16)sport << 16) + (__force u16)dport; | ||
| 1544 | hash[3] = keyptr->secret[11]; | ||
| 1545 | |||
| 1546 | seq = half_md4_transform(hash, keyptr->secret) & HASH_MASK; | ||
| 1547 | seq += keyptr->count; | ||
| 1548 | /* | ||
| 1549 | * As close as possible to RFC 793, which | ||
| 1550 | * suggests using a 250 kHz clock. | ||
| 1551 | * Further reading shows this assumes 2 Mb/s networks. | ||
| 1552 | * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. | ||
| 1553 | * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but | ||
| 1554 | * we also need to limit the resolution so that the u32 seq | ||
| 1555 | * overlaps less than one time per MSL (2 minutes). | ||
| 1556 | * Choosing a clock of 64 ns period is OK. (period of 274 s) | ||
| 1557 | */ | ||
| 1558 | seq += ktime_to_ns(ktime_get_real()) >> 6; | ||
| 1559 | |||
| 1560 | return seq; | ||
| 1561 | } | ||
| 1562 | |||
| 1563 | /* Generate secure starting point for ephemeral IPV4 transport port search */ | ||
| 1564 | u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) | ||
| 1565 | { | ||
| 1566 | struct keydata *keyptr = get_keyptr(); | ||
| 1567 | u32 hash[4]; | ||
| 1568 | |||
| 1569 | /* | ||
| 1570 | * Pick a unique starting offset for each ephemeral port search | ||
| 1571 | * (saddr, daddr, dport) and 48bits of random data. | ||
| 1572 | */ | ||
| 1573 | hash[0] = (__force u32)saddr; | ||
| 1574 | hash[1] = (__force u32)daddr; | ||
| 1575 | hash[2] = (__force u32)dport ^ keyptr->secret[10]; | ||
| 1576 | hash[3] = keyptr->secret[11]; | ||
| 1577 | |||
| 1578 | return half_md4_transform(hash, keyptr->secret); | ||
| 1579 | } | ||
| 1580 | EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral); | ||
| 1581 | |||
| 1582 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 1583 | u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, | ||
| 1584 | __be16 dport) | ||
| 1585 | { | ||
| 1586 | struct keydata *keyptr = get_keyptr(); | ||
| 1587 | u32 hash[12]; | ||
| 1588 | |||
| 1589 | memcpy(hash, saddr, 16); | ||
| 1590 | hash[4] = (__force u32)dport; | ||
| 1591 | memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7); | ||
| 1592 | |||
| 1593 | return twothirdsMD4Transform((const __u32 *)daddr, hash); | ||
| 1594 | } | ||
| 1595 | #endif | ||
| 1596 | |||
| 1597 | #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) | ||
| 1598 | /* Similar to secure_tcp_sequence_number but generate a 48 bit value | ||
| 1599 | * bit's 32-47 increase every key exchange | ||
| 1600 | * 0-31 hash(source, dest) | ||
| 1601 | */ | ||
| 1602 | u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, | ||
| 1603 | __be16 sport, __be16 dport) | ||
| 1604 | { | ||
| 1605 | u64 seq; | ||
| 1606 | __u32 hash[4]; | ||
| 1607 | struct keydata *keyptr = get_keyptr(); | ||
| 1608 | |||
| 1609 | hash[0] = (__force u32)saddr; | ||
| 1610 | hash[1] = (__force u32)daddr; | ||
| 1611 | hash[2] = ((__force u16)sport << 16) + (__force u16)dport; | ||
| 1612 | hash[3] = keyptr->secret[11]; | ||
| 1613 | |||
| 1614 | seq = half_md4_transform(hash, keyptr->secret); | ||
| 1615 | seq |= ((u64)keyptr->count) << (32 - HASH_BITS); | ||
| 1616 | |||
| 1617 | seq += ktime_to_ns(ktime_get_real()); | ||
| 1618 | seq &= (1ull << 48) - 1; | ||
| 1619 | |||
| 1620 | return seq; | ||
| 1621 | } | ||
| 1622 | EXPORT_SYMBOL(secure_dccp_sequence_number); | ||
| 1623 | #endif | ||
| 1624 | |||
| 1625 | #endif /* CONFIG_INET */ | ||
| 1626 | |||
| 1627 | 1311 | ||
| 1628 | /* | 1312 | /* |
| 1629 | * Get a random word for internal kernel use only. Similar to urandom but | 1313 | * Get a random word for internal kernel use only. Similar to urandom but |
| @@ -1631,17 +1315,15 @@ EXPORT_SYMBOL(secure_dccp_sequence_number); | |||
| 1631 | * value is not cryptographically secure but for several uses the cost of | 1315 | * value is not cryptographically secure but for several uses the cost of |
| 1632 | * depleting entropy is too high | 1316 | * depleting entropy is too high |
| 1633 | */ | 1317 | */ |
| 1634 | DEFINE_PER_CPU(__u32 [4], get_random_int_hash); | 1318 | DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash); |
| 1635 | unsigned int get_random_int(void) | 1319 | unsigned int get_random_int(void) |
| 1636 | { | 1320 | { |
| 1637 | struct keydata *keyptr; | ||
| 1638 | __u32 *hash = get_cpu_var(get_random_int_hash); | 1321 | __u32 *hash = get_cpu_var(get_random_int_hash); |
| 1639 | int ret; | 1322 | unsigned int ret; |
| 1640 | 1323 | ||
| 1641 | keyptr = get_keyptr(); | ||
| 1642 | hash[0] += current->pid + jiffies + get_cycles(); | 1324 | hash[0] += current->pid + jiffies + get_cycles(); |
| 1643 | 1325 | md5_transform(hash, random_int_secret); | |
| 1644 | ret = half_md4_transform(hash, keyptr->secret); | 1326 | ret = hash[0]; |
| 1645 | put_cpu_var(get_random_int_hash); | 1327 | put_cpu_var(get_random_int_hash); |
| 1646 | 1328 | ||
| 1647 | return ret; | 1329 | return ret; |
