diff options
author | Benoît Ganne <bganne@cisco.com> | 2022-01-18 15:56:41 +0100 |
---|---|---|
committer | Beno�t Ganne <bganne@cisco.com> | 2023-03-23 08:59:31 +0000 |
commit | 5527a78ed96043d2c26e3271066c50b44dd7fc0b (patch) | |
tree | 3e4186cb439e10051d013cc71c1f7d8d81ad9613 /src/vppinfra | |
parent | ad95b06181c354291f4433c5e550cb89c5122252 (diff) |
ipsec: make pre-shared keys harder to misuse
Using pre-shared keys is usually a bad idea, one should use eg. IKEv2
instead, but one does not always have the choice.
For AES-CBC, the IV must be unpredictable (see NIST SP800-38a Appendix
C) whereas for AES-CTR or AES-GCM, the IV should never be reused with
the same key material (see NIST SP800-38a Appendix B and NIST SP800-38d
section 8).
If one uses pre-shared keys and VPP is restarted, the IV counter
restarts at 0 and the same IVs are generated with the same pre-shared
keys materials.
To fix those issues we follow the recommendation from NIST SP800-38a
and NIST SP800-38d:
- we use a PRNG (not cryptographically secured) to generate IVs to
avoid generating the same IV sequence between VPP restarts. The PRNG is
chosen so that there is a low chance of generating the same sequence
- for AES-CBC, the generated IV is encrypted as part of the message.
This makes the (predictable) PRNG-generated IV unpredictable as it is
encrypted with the secret key
- for AES-CTR and GCM, we use the IV as-is as predictable IVs are fine
Most of the changes in this patch are caused by the need to shoehorn an
additional state of 2 u64 for the PRNG in the 1st cacheline of the SA
object.
Type: improvement
Change-Id: I2af89c21ae4b2c4c33dd21aeffcfb79c13c9d84c
Signed-off-by: Benoît Ganne <bganne@cisco.com>
Diffstat (limited to 'src/vppinfra')
-rw-r--r-- | src/vppinfra/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/vppinfra/pcg.h | 85 |
2 files changed, 86 insertions, 0 deletions
diff --git a/src/vppinfra/CMakeLists.txt b/src/vppinfra/CMakeLists.txt index 4a9c008b65e..975bf503827 100644 --- a/src/vppinfra/CMakeLists.txt +++ b/src/vppinfra/CMakeLists.txt @@ -158,6 +158,7 @@ set(VPPINFRA_HEADERS os.h pcap.h pcap_funcs.h + pcg.h perfmon/perfmon.h pmalloc.h pool.h diff --git a/src/vppinfra/pcg.h b/src/vppinfra/pcg.h new file mode 100644 index 00000000000..a7cc9201b8f --- /dev/null +++ b/src/vppinfra/pcg.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2022 Cisco and/or its affiliates. + * Licensed 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. + */ +/* + * PCG Random Number Generation for C. + * + * Copyright 2014-2019 Melissa O'Neill <oneill@pcg-random.org>, + * and the PCG Project contributors. + * + * SPDX-License-Identifier: (Apache-2.0 OR MIT) + * + * Licensed under the Apache License, Version 2.0 (provided in + * LICENSE-APACHE.txt and at http://www.apache.org/licenses/LICENSE-2.0) + * or under the MIT license (provided in LICENSE-MIT.txt and at + * http://opensource.org/licenses/MIT), at your option. This file may not + * be copied, modified, or distributed except according to those terms. + * + * Distributed on an "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See your chosen license for details. + * + * For additional information about the PCG random number generation scheme, + * visit http://www.pcg-random.org/. + */ + +/* This implements the pcg64i_random_t PCG specialized generator: + * https://www.pcg-random.org/using-pcg-c.html#specialized-generators + * This generator produces each 64-bits output exactly once, which is + * perfectly suited to generated non-repeating IVs. However, because of this + * property the entire internal state is revealed with each output. + * It has a 2^64 period and supports 2^63 non-overlaping streams */ + +#define clib_pcg64i_random_r clib_pcg_setseq_64_rxs_m_xs_64_random_r +#define clib_pcg64i_srandom_r clib_pcg_setseq_64_srandom_r + +typedef struct +{ + u64 state; + u64 inc; +} clib_pcg_state_setseq_64_t; + +typedef clib_pcg_state_setseq_64_t clib_pcg64i_random_t; + +static_always_inline void +clib_pcg_setseq_64_step_r (clib_pcg_state_setseq_64_t *rng) +{ + rng->state = rng->state * 6364136223846793005ULL + rng->inc; +} + +static_always_inline u64 +clib_pcg_output_rxs_m_xs_64_64 (u64 state) +{ + u64 word = + ((state >> ((state >> 59u) + 5u)) ^ state) * 12605985483714917081ull; + return (word >> 43u) ^ word; +} + +static_always_inline u64 +clib_pcg_setseq_64_rxs_m_xs_64_random_r (clib_pcg_state_setseq_64_t *rng) +{ + u64 oldstate = rng->state; + clib_pcg_setseq_64_step_r (rng); + return clib_pcg_output_rxs_m_xs_64_64 (oldstate); +} + +static_always_inline void +clib_pcg_setseq_64_srandom_r (clib_pcg_state_setseq_64_t *rng, u64 initstate, + u64 initseq) +{ + rng->state = 0U; + rng->inc = (initseq << 1u) | 1u; + clib_pcg_setseq_64_step_r (rng); + rng->state += initstate; + clib_pcg_setseq_64_step_r (rng); +} |