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