From 5096a2c9fdfcd7838a8dc015a3185b3a2b2a4849 Mon Sep 17 00:00:00 2001 From: Zhe Weng Date: Wed, 1 Nov 2023 11:59:51 +0800 Subject: [PATCH] net/tcp: Take out get random process as common function Signed-off-by: Zhe Weng --- net/tcp/tcp_conn.c | 18 ++------- net/tcp/tcp_seqno.c | 23 ++--------- net/utils/CMakeLists.txt | 3 +- net/utils/Make.defs | 2 +- net/utils/net_getrandom.c | 82 +++++++++++++++++++++++++++++++++++++++ net/utils/utils.h | 15 +++++++ 6 files changed, 107 insertions(+), 36 deletions(-) create mode 100644 net/utils/net_getrandom.c diff --git a/net/tcp/tcp_conn.c b/net/tcp/tcp_conn.c index 3bc6fccddf..3a681eea17 100644 --- a/net/tcp/tcp_conn.c +++ b/net/tcp/tcp_conn.c @@ -49,7 +49,6 @@ #include #include #include -#include #include @@ -70,6 +69,7 @@ #include "icmpv6/icmpv6.h" #include "nat/nat.h" #include "netdev/netdev.h" +#include "utils/utils.h" /**************************************************************************** * Private Data @@ -579,26 +579,14 @@ int tcp_selectport(uint8_t domain, uint16_t portno) { static uint16_t g_last_tcp_port; - ssize_t ret; /* Generate port base dynamically */ if (g_last_tcp_port == 0) { - ret = getrandom(&g_last_tcp_port, sizeof(uint16_t), 0); - if (ret < 0) - { - ret = getrandom(&g_last_tcp_port, sizeof(uint16_t), GRND_RANDOM); - } + net_getrandom(&g_last_tcp_port, sizeof(uint16_t)); - if (ret != sizeof(uint16_t)) - { - g_last_tcp_port = clock_systime_ticks() % 32000; - } - else - { - g_last_tcp_port = g_last_tcp_port % 32000; - } + g_last_tcp_port = g_last_tcp_port % 32000; if (g_last_tcp_port < 4096) { diff --git a/net/tcp/tcp_seqno.c b/net/tcp/tcp_seqno.c index eeaa1d43c1..e68ad9cf2d 100644 --- a/net/tcp/tcp_seqno.c +++ b/net/tcp/tcp_seqno.c @@ -45,13 +45,13 @@ #include #include -#include #include #include #include #include "devif/devif.h" +#include "utils/utils.h" /**************************************************************************** * Private Data @@ -144,32 +144,17 @@ uint32_t tcp_addsequence(FAR uint8_t *seqno, uint16_t len) void tcp_initsequence(FAR uint8_t *seqno) { - int ret; - /* If g_tcpsequence is already initialized, just copy it */ if (g_tcpsequence == 0) { /* Get a random TCP sequence number */ - ret = getrandom(&g_tcpsequence, sizeof(uint32_t), 0); - if (ret < 0) - { - ret = getrandom(&g_tcpsequence, sizeof(uint32_t), GRND_RANDOM); - } + net_getrandom(&g_tcpsequence, sizeof(uint32_t)); - /* If getrandom() failed use sys ticks, use about half of allowed - * values - */ + /* Use about half of allowed values */ - if (ret != sizeof(uint32_t)) - { - g_tcpsequence = clock_systime_ticks() % 2000000000; - } - else - { - g_tcpsequence = g_tcpsequence % 2000000000; - } + g_tcpsequence = g_tcpsequence % 2000000000; /* If the random value is "small" increase it */ diff --git a/net/utils/CMakeLists.txt b/net/utils/CMakeLists.txt index 9cbfd8cc89..8c779bfe0b 100644 --- a/net/utils/CMakeLists.txt +++ b/net/utils/CMakeLists.txt @@ -30,7 +30,8 @@ set(SRCS net_lock.c net_snoop.c net_cmsg.c - net_iob_concat.c) + net_iob_concat.c + net_getrandom.c) # IPv6 utilities diff --git a/net/utils/Make.defs b/net/utils/Make.defs index 3ee0274495..400d0367fb 100644 --- a/net/utils/Make.defs +++ b/net/utils/Make.defs @@ -22,7 +22,7 @@ NET_CSRCS += net_dsec2tick.c net_dsec2timeval.c net_timeval2dsec.c NET_CSRCS += net_chksum.c net_ipchksum.c net_incr32.c net_lock.c net_snoop.c -NET_CSRCS += net_cmsg.c net_iob_concat.c +NET_CSRCS += net_cmsg.c net_iob_concat.c net_getrandom.c # IPv6 utilities diff --git a/net/utils/net_getrandom.c b/net/utils/net_getrandom.c new file mode 100644 index 0000000000..00ed6fb833 --- /dev/null +++ b/net/utils/net_getrandom.c @@ -0,0 +1,82 @@ +/**************************************************************************** + * net/utils/net_getrandom.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: net_getrandom + * + * Description: + * Fill a buffer of arbitrary length with randomness. This function is + * guaranteed to be success. + * + * Input Parameters: + * bytes - Buffer for returned random bytes + * nbytes - Number of bytes requested. + * + ****************************************************************************/ + +void net_getrandom(FAR void *bytes, size_t nbytes) +{ +#if defined(CONFIG_DEV_URANDOM) || defined(CONFIG_DEV_RANDOM) + ssize_t ret = getrandom(bytes, nbytes, 0); + + if (ret < 0) + { + ret = getrandom(bytes, nbytes, GRND_RANDOM); + } + + if (ret == nbytes) + { + return; + } +#endif + + /* Fallback to hash of clock_systime_ticks(), minus nbytes to avoid getting + * same tick count when looping more than once. + */ + + while (nbytes > 0) + { + uint32_t hash = HASH(clock_systime_ticks() - nbytes, 32); + size_t ncopy = MIN(nbytes, sizeof(hash)); + + memcpy(bytes, &hash, ncopy); + + nbytes -= ncopy; + bytes = (FAR uint8_t *)bytes + ncopy; + } +} diff --git a/net/utils/utils.h b/net/utils/utils.h index 00eae795e5..401f2e1161 100644 --- a/net/utils/utils.h +++ b/net/utils/utils.h @@ -144,6 +144,21 @@ unsigned int net_dsec2tick(int dsec); unsigned int net_timeval2dsec(FAR struct timeval *tv, enum tv2ds_remainder_e remainder); +/**************************************************************************** + * Name: net_getrandom + * + * Description: + * Fill a buffer of arbitrary length with randomness. This function is + * guaranteed to be success. + * + * Input Parameters: + * bytes - Buffer for returned random bytes + * nbytes - Number of bytes requested. + * + ****************************************************************************/ + +void net_getrandom(FAR void *bytes, size_t nbytes); + /**************************************************************************** * Name: net_ipv6_mask2pref *