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