xref: /freebsd/crypto/openssl/include/internal/quic_vlint.h (revision e7be843b4a162e68651d3911f0357ed464915629)
1*e7be843bSPierre Pronchery /*
2*e7be843bSPierre Pronchery * Copyright 2022-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_VLINT_H
11*e7be843bSPierre Pronchery # define OSSL_INTERNAL_QUIC_VLINT_H
12*e7be843bSPierre Pronchery # pragma once
13*e7be843bSPierre Pronchery 
14*e7be843bSPierre Pronchery # include "internal/e_os.h"
15*e7be843bSPierre Pronchery 
16*e7be843bSPierre Pronchery # ifndef OPENSSL_NO_QUIC
17*e7be843bSPierre Pronchery 
18*e7be843bSPierre Pronchery /* The smallest value requiring a 1, 2, 4, or 8-byte representation. */
19*e7be843bSPierre Pronchery #define OSSL_QUIC_VLINT_1B_MIN 0
20*e7be843bSPierre Pronchery #define OSSL_QUIC_VLINT_2B_MIN 64
21*e7be843bSPierre Pronchery #define OSSL_QUIC_VLINT_4B_MIN 16384
22*e7be843bSPierre Pronchery #define OSSL_QUIC_VLINT_8B_MIN 1073741824
23*e7be843bSPierre Pronchery 
24*e7be843bSPierre Pronchery /* The largest value representable in a given number of bytes. */
25*e7be843bSPierre Pronchery #define OSSL_QUIC_VLINT_1B_MAX (OSSL_QUIC_VLINT_2B_MIN - 1)
26*e7be843bSPierre Pronchery #define OSSL_QUIC_VLINT_2B_MAX (OSSL_QUIC_VLINT_4B_MIN - 1)
27*e7be843bSPierre Pronchery #define OSSL_QUIC_VLINT_4B_MAX (OSSL_QUIC_VLINT_8B_MIN - 1)
28*e7be843bSPierre Pronchery #define OSSL_QUIC_VLINT_8B_MAX (((uint64_t)1 << 62) - 1)
29*e7be843bSPierre Pronchery 
30*e7be843bSPierre Pronchery /* The largest value representable as a variable-length integer. */
31*e7be843bSPierre Pronchery #define OSSL_QUIC_VLINT_MAX    OSSL_QUIC_VLINT_8B_MAX
32*e7be843bSPierre Pronchery 
33*e7be843bSPierre Pronchery /*
34*e7be843bSPierre Pronchery  * Returns the number of bytes needed to encode v in the QUIC variable-length
35*e7be843bSPierre Pronchery  * integer encoding.
36*e7be843bSPierre Pronchery  *
37*e7be843bSPierre Pronchery  * Returns 0 if v exceeds OSSL_QUIC_VLINT_MAX.
38*e7be843bSPierre Pronchery  */
ossl_quic_vlint_encode_len(uint64_t v)39*e7be843bSPierre Pronchery static ossl_unused ossl_inline size_t ossl_quic_vlint_encode_len(uint64_t v)
40*e7be843bSPierre Pronchery {
41*e7be843bSPierre Pronchery     if (v < OSSL_QUIC_VLINT_2B_MIN)
42*e7be843bSPierre Pronchery         return 1;
43*e7be843bSPierre Pronchery 
44*e7be843bSPierre Pronchery     if (v < OSSL_QUIC_VLINT_4B_MIN)
45*e7be843bSPierre Pronchery         return 2;
46*e7be843bSPierre Pronchery 
47*e7be843bSPierre Pronchery     if (v < OSSL_QUIC_VLINT_8B_MIN)
48*e7be843bSPierre Pronchery         return 4;
49*e7be843bSPierre Pronchery 
50*e7be843bSPierre Pronchery     if (v <= OSSL_QUIC_VLINT_MAX)
51*e7be843bSPierre Pronchery         return 8;
52*e7be843bSPierre Pronchery 
53*e7be843bSPierre Pronchery     return 0;
54*e7be843bSPierre Pronchery }
55*e7be843bSPierre Pronchery 
56*e7be843bSPierre Pronchery /*
57*e7be843bSPierre Pronchery  * This function writes a QUIC varable-length encoded integer to buf.
58*e7be843bSPierre Pronchery  * The smallest usable representation is used.
59*e7be843bSPierre Pronchery  *
60*e7be843bSPierre Pronchery  * It is the caller's responsibility to ensure that the buffer is big enough by
61*e7be843bSPierre Pronchery  * calling ossl_quic_vlint_encode_len(v) before calling this function.
62*e7be843bSPierre Pronchery  *
63*e7be843bSPierre Pronchery  * Precondition: buf is at least ossl_quic_vlint_enc_len(v) bytes in size
64*e7be843bSPierre Pronchery  *   (unchecked)
65*e7be843bSPierre Pronchery  * Precondition: v does not exceed OSSL_QUIC_VLINT_MAX
66*e7be843bSPierre Pronchery  *   (unchecked)
67*e7be843bSPierre Pronchery  */
68*e7be843bSPierre Pronchery void ossl_quic_vlint_encode(unsigned char *buf, uint64_t v);
69*e7be843bSPierre Pronchery 
70*e7be843bSPierre Pronchery /*
71*e7be843bSPierre Pronchery  * This function writes a QUIC variable-length encoded integer to buf. The
72*e7be843bSPierre Pronchery  * specified number of bytes n are used for the encoding, which means that the
73*e7be843bSPierre Pronchery  * encoded value may take up more space than necessary.
74*e7be843bSPierre Pronchery  *
75*e7be843bSPierre Pronchery  * It is the caller's responsibility to ensure that the buffer is of at least n
76*e7be843bSPierre Pronchery  * bytes, and that v is representable by a n-byte QUIC variable-length integer.
77*e7be843bSPierre Pronchery  * The representable ranges are:
78*e7be843bSPierre Pronchery  *
79*e7be843bSPierre Pronchery  *   1-byte encoding: [0, 2** 6-1]
80*e7be843bSPierre Pronchery  *   2-byte encoding: [0, 2**14-1]
81*e7be843bSPierre Pronchery  *   4-byte encoding: [0, 2**30-1]
82*e7be843bSPierre Pronchery  *   8-byte encoding: [0, 2**62-1]
83*e7be843bSPierre Pronchery  *
84*e7be843bSPierre Pronchery  * Precondition: buf is at least n bytes in size (unchecked)
85*e7be843bSPierre Pronchery  * Precondition: v does not exceed the representable range
86*e7be843bSPierre Pronchery  *   (ossl_quic_vlint_encode_len(v) <= n) (unchecked)
87*e7be843bSPierre Pronchery  * Precondition: v does not exceed OSSL_QUIC_VLINT_MAX
88*e7be843bSPierre Pronchery  *   (unchecked)
89*e7be843bSPierre Pronchery  */
90*e7be843bSPierre Pronchery void ossl_quic_vlint_encode_n(unsigned char *buf, uint64_t v, int n);
91*e7be843bSPierre Pronchery 
92*e7be843bSPierre Pronchery /*
93*e7be843bSPierre Pronchery  * Given the first byte of an encoded QUIC variable-length integer, returns
94*e7be843bSPierre Pronchery  * the number of bytes comprising the encoded integer, including the first
95*e7be843bSPierre Pronchery  * byte.
96*e7be843bSPierre Pronchery  */
ossl_quic_vlint_decode_len(uint8_t first_byte)97*e7be843bSPierre Pronchery static ossl_unused ossl_inline size_t ossl_quic_vlint_decode_len(uint8_t first_byte)
98*e7be843bSPierre Pronchery {
99*e7be843bSPierre Pronchery     return 1U << ((first_byte & 0xC0) >> 6);
100*e7be843bSPierre Pronchery }
101*e7be843bSPierre Pronchery 
102*e7be843bSPierre Pronchery /*
103*e7be843bSPierre Pronchery  * Given a buffer containing an encoded QUIC variable-length integer, returns
104*e7be843bSPierre Pronchery  * the decoded value. The buffer must be of at least
105*e7be843bSPierre Pronchery  * ossl_quic_vlint_decode_len(buf[0]) bytes in size, and the caller is responsible
106*e7be843bSPierre Pronchery  * for checking this.
107*e7be843bSPierre Pronchery  *
108*e7be843bSPierre Pronchery  * Precondition: buf is at least ossl_quic_vlint_decode_len(buf[0]) bytes in size
109*e7be843bSPierre Pronchery  *   (unchecked)
110*e7be843bSPierre Pronchery  */
111*e7be843bSPierre Pronchery uint64_t ossl_quic_vlint_decode_unchecked(const unsigned char *buf);
112*e7be843bSPierre Pronchery 
113*e7be843bSPierre Pronchery /*
114*e7be843bSPierre Pronchery  * Given a buffer buf of buf_len bytes in length, attempts to decode an encoded
115*e7be843bSPierre Pronchery  * QUIC variable-length integer at the start of the buffer and writes the result
116*e7be843bSPierre Pronchery  * to *v. If buf_len is inadequate, suggesting a truncated encoded integer, the
117*e7be843bSPierre Pronchery  * function fails and 0 is returned. Otherwise, returns the number of bytes
118*e7be843bSPierre Pronchery  * consumed.
119*e7be843bSPierre Pronchery  *
120*e7be843bSPierre Pronchery  * Precondition: buf is at least buf_len bytes in size
121*e7be843bSPierre Pronchery  * Precondition: v (unchecked)
122*e7be843bSPierre Pronchery  */
123*e7be843bSPierre Pronchery int ossl_quic_vlint_decode(const unsigned char *buf, size_t buf_len, uint64_t *v);
124*e7be843bSPierre Pronchery 
125*e7be843bSPierre Pronchery # endif
126*e7be843bSPierre Pronchery 
127*e7be843bSPierre Pronchery #endif
128