1*e7be843bSPierre Pronchery /* 2*e7be843bSPierre Pronchery * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. 3*e7be843bSPierre Pronchery * 4*e7be843bSPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use 5*e7be843bSPierre Pronchery * this file except in compliance with the License. You can obtain a copy 6*e7be843bSPierre Pronchery * in the file LICENSE in the source distribution or at 7*e7be843bSPierre Pronchery * https://www.openssl.org/source/license.html 8*e7be843bSPierre Pronchery */ 9*e7be843bSPierre Pronchery 10*e7be843bSPierre Pronchery #ifndef OSSL_INTERNAL_QUIC_SRTM_H 11*e7be843bSPierre Pronchery # define OSSL_INTERNAL_QUIC_SRTM_H 12*e7be843bSPierre Pronchery # pragma once 13*e7be843bSPierre Pronchery 14*e7be843bSPierre Pronchery # include "internal/e_os.h" 15*e7be843bSPierre Pronchery # include "internal/time.h" 16*e7be843bSPierre Pronchery # include "internal/quic_types.h" 17*e7be843bSPierre Pronchery # include "internal/quic_wire.h" 18*e7be843bSPierre Pronchery # include "internal/quic_predef.h" 19*e7be843bSPierre Pronchery 20*e7be843bSPierre Pronchery # ifndef OPENSSL_NO_QUIC 21*e7be843bSPierre Pronchery 22*e7be843bSPierre Pronchery /* 23*e7be843bSPierre Pronchery * QUIC Stateless Reset Token Manager 24*e7be843bSPierre Pronchery * ================================== 25*e7be843bSPierre Pronchery * 26*e7be843bSPierre Pronchery * The stateless reset token manager is responsible for mapping stateless reset 27*e7be843bSPierre Pronchery * tokens to connections. It is used to identify stateless reset tokens in 28*e7be843bSPierre Pronchery * incoming packets. In this regard it can be considered an alternate "routing" 29*e7be843bSPierre Pronchery * mechanism for incoming packets, and is somewhat analogous with the LCIDM, 30*e7be843bSPierre Pronchery * except that it uses SRTs to route rather than DCIDs. 31*e7be843bSPierre Pronchery * 32*e7be843bSPierre Pronchery * The SRTM specifically stores a bidirectional mapping of the form 33*e7be843bSPierre Pronchery * 34*e7be843bSPierre Pronchery * (opaque pointer, sequence number) [1] <-> [0..n] SRT 35*e7be843bSPierre Pronchery * 36*e7be843bSPierre Pronchery * The (opaque pointer, sequence number) tuple is used to refer to an entry (for 37*e7be843bSPierre Pronchery * example for the purposes of removing it later when it is no longer needed). 38*e7be843bSPierre Pronchery * Likewise, an entry can be looked up using SRT to get the opaque pointer and 39*e7be843bSPierre Pronchery * sequence number. 40*e7be843bSPierre Pronchery * 41*e7be843bSPierre Pronchery * It is important to note that the same SRT may exist multiple times and map to 42*e7be843bSPierre Pronchery * multiple (opaque pointer, sequence number) tuples, for example, if we 43*e7be843bSPierre Pronchery * initiate multiple connections to the same peer using the same local QUIC_PORT 44*e7be843bSPierre Pronchery * and the peer decides to behave bizarrely and issue the same SRT for both 45*e7be843bSPierre Pronchery * connections. It should not do this, but we have to be resilient against 46*e7be843bSPierre Pronchery * byzantine peer behaviour. Thus we are capable of storing multiple identical 47*e7be843bSPierre Pronchery * SRTs for different (opaque pointer, sequence number) keys. 48*e7be843bSPierre Pronchery * 49*e7be843bSPierre Pronchery * The SRTM supports arbitrary insertion, arbitrary deletion of specific keys 50*e7be843bSPierre Pronchery * identified by a (opaque pointer, sequence number) key, and mass deletion of 51*e7be843bSPierre Pronchery * all entries under a specific opaque pointer. It supports lookup by SRT to 52*e7be843bSPierre Pronchery * identify zero or more corresponding (opaque pointer, sequence number) tuples. 53*e7be843bSPierre Pronchery * 54*e7be843bSPierre Pronchery * The opaque pointer may be used for any purpose but is intended to represent a 55*e7be843bSPierre Pronchery * connection identity and must therefore be consistent (usefully comparable). 56*e7be843bSPierre Pronchery */ 57*e7be843bSPierre Pronchery 58*e7be843bSPierre Pronchery /* Creates a new empty SRTM instance. */ 59*e7be843bSPierre Pronchery QUIC_SRTM *ossl_quic_srtm_new(OSSL_LIB_CTX *libctx, const char *propq); 60*e7be843bSPierre Pronchery 61*e7be843bSPierre Pronchery /* Frees a SRTM instance. No-op if srtm is NULL. */ 62*e7be843bSPierre Pronchery void ossl_quic_srtm_free(QUIC_SRTM *srtm); 63*e7be843bSPierre Pronchery 64*e7be843bSPierre Pronchery /* 65*e7be843bSPierre Pronchery * Add a (opaque, seq_num) -> SRT entry to the SRTM. This operation fails if a 66*e7be843bSPierre Pronchery * SRT entry already exists with the same (opaque, seq_num) tuple. The token is 67*e7be843bSPierre Pronchery * copied. Returns 1 on success or 0 on failure. 68*e7be843bSPierre Pronchery */ 69*e7be843bSPierre Pronchery int ossl_quic_srtm_add(QUIC_SRTM *srtm, void *opaque, uint64_t seq_num, 70*e7be843bSPierre Pronchery const QUIC_STATELESS_RESET_TOKEN *token); 71*e7be843bSPierre Pronchery 72*e7be843bSPierre Pronchery /* 73*e7be843bSPierre Pronchery * Removes an entry by identifying it via its (opaque, seq_num) tuple. 74*e7be843bSPierre Pronchery * Returns 1 if the entry was found and removed, and 0 if it was not found. 75*e7be843bSPierre Pronchery */ 76*e7be843bSPierre Pronchery int ossl_quic_srtm_remove(QUIC_SRTM *srtm, void *opaque, uint64_t seq_num); 77*e7be843bSPierre Pronchery 78*e7be843bSPierre Pronchery /* 79*e7be843bSPierre Pronchery * Removes all entries (opaque, *) with the given opaque pointer. 80*e7be843bSPierre Pronchery * 81*e7be843bSPierre Pronchery * Returns 1 on success and 0 on failure. If no entries with the given opaque 82*e7be843bSPierre Pronchery * pointer were found, this is considered a success condition. 83*e7be843bSPierre Pronchery */ 84*e7be843bSPierre Pronchery int ossl_quic_srtm_cull(QUIC_SRTM *strm, void *opaque); 85*e7be843bSPierre Pronchery 86*e7be843bSPierre Pronchery /* 87*e7be843bSPierre Pronchery * Looks up a SRT to find the corresponding opaque pointer and sequence number. 88*e7be843bSPierre Pronchery * An output field pointer can be set to NULL if it is not required. 89*e7be843bSPierre Pronchery * 90*e7be843bSPierre Pronchery * This function is designed to avoid exposing timing channels on token values 91*e7be843bSPierre Pronchery * or the contents of the SRT mapping. 92*e7be843bSPierre Pronchery * 93*e7be843bSPierre Pronchery * If there are several identical SRTs, idx can be used to get the nth entry. 94*e7be843bSPierre Pronchery * Call this function with idx set to 0 first, and keep calling it after 95*e7be843bSPierre Pronchery * incrementing idx until it returns 0. 96*e7be843bSPierre Pronchery * 97*e7be843bSPierre Pronchery * Returns 1 if an entry was found and 0 otherwise. 98*e7be843bSPierre Pronchery */ 99*e7be843bSPierre Pronchery int ossl_quic_srtm_lookup(QUIC_SRTM *srtm, 100*e7be843bSPierre Pronchery const QUIC_STATELESS_RESET_TOKEN *token, 101*e7be843bSPierre Pronchery size_t idx, 102*e7be843bSPierre Pronchery void **opaque, uint64_t *seq_num); 103*e7be843bSPierre Pronchery 104*e7be843bSPierre Pronchery /* Verify internal invariants and assert if they are not met. */ 105*e7be843bSPierre Pronchery void ossl_quic_srtm_check(const QUIC_SRTM *srtm); 106*e7be843bSPierre Pronchery 107*e7be843bSPierre Pronchery # endif 108*e7be843bSPierre Pronchery 109*e7be843bSPierre Pronchery #endif 110