aboutsummaryrefslogtreecommitdiff
path: root/crypto/quic_vlint.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/quic_vlint.c')
-rw-r--r--crypto/quic_vlint.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/crypto/quic_vlint.c b/crypto/quic_vlint.c
new file mode 100644
index 000000000000..023898596319
--- /dev/null
+++ b/crypto/quic_vlint.c
@@ -0,0 +1,81 @@
+#include "internal/quic_vlint.h"
+#include "internal/e_os.h"
+
+#ifndef OPENSSL_NO_QUIC
+
+void ossl_quic_vlint_encode_n(uint8_t *buf, uint64_t v, int n)
+{
+ if (n == 1) {
+ buf[0] = (uint8_t)v;
+ } else if (n == 2) {
+ buf[0] = (uint8_t)(0x40 | ((v >> 8) & 0x3F));
+ buf[1] = (uint8_t)v;
+ } else if (n == 4) {
+ buf[0] = (uint8_t)(0x80 | ((v >> 24) & 0x3F));
+ buf[1] = (uint8_t)(v >> 16);
+ buf[2] = (uint8_t)(v >> 8);
+ buf[3] = (uint8_t)v;
+ } else {
+ buf[0] = (uint8_t)(0xC0 | ((v >> 56) & 0x3F));
+ buf[1] = (uint8_t)(v >> 48);
+ buf[2] = (uint8_t)(v >> 40);
+ buf[3] = (uint8_t)(v >> 32);
+ buf[4] = (uint8_t)(v >> 24);
+ buf[5] = (uint8_t)(v >> 16);
+ buf[6] = (uint8_t)(v >> 8);
+ buf[7] = (uint8_t)v;
+ }
+}
+
+void ossl_quic_vlint_encode(uint8_t *buf, uint64_t v)
+{
+ ossl_quic_vlint_encode_n(buf, v, ossl_quic_vlint_encode_len(v));
+}
+
+uint64_t ossl_quic_vlint_decode_unchecked(const unsigned char *buf)
+{
+ uint8_t first_byte = buf[0];
+ size_t sz = ossl_quic_vlint_decode_len(first_byte);
+
+ if (sz == 1)
+ return first_byte & 0x3F;
+
+ if (sz == 2)
+ return ((uint64_t)(first_byte & 0x3F) << 8)
+ | buf[1];
+
+ if (sz == 4)
+ return ((uint64_t)(first_byte & 0x3F) << 24)
+ | ((uint64_t)buf[1] << 16)
+ | ((uint64_t)buf[2] << 8)
+ | buf[3];
+
+ return ((uint64_t)(first_byte & 0x3F) << 56)
+ | ((uint64_t)buf[1] << 48)
+ | ((uint64_t)buf[2] << 40)
+ | ((uint64_t)buf[3] << 32)
+ | ((uint64_t)buf[4] << 24)
+ | ((uint64_t)buf[5] << 16)
+ | ((uint64_t)buf[6] << 8)
+ | buf[7];
+}
+
+int ossl_quic_vlint_decode(const unsigned char *buf, size_t buf_len, uint64_t *v)
+{
+ size_t dec_len;
+ uint64_t x;
+
+ if (buf_len < 1)
+ return 0;
+
+ dec_len = ossl_quic_vlint_decode_len(buf[0]);
+ if (buf_len < dec_len)
+ return 0;
+
+ x = ossl_quic_vlint_decode_unchecked(buf);
+
+ *v = x;
+ return dec_len;
+}
+
+#endif