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 128