xref: /openssl/crypto/quic_vlint.c (revision 6292519c)
1 #include "internal/quic_vlint.h"
2 #include "internal/e_os.h"
3 
4 #ifndef OPENSSL_NO_QUIC
5 
ossl_quic_vlint_encode_n(uint8_t * buf,uint64_t v,int n)6 void ossl_quic_vlint_encode_n(uint8_t *buf, uint64_t v, int n)
7 {
8     if (n == 1) {
9         buf[0] = (uint8_t)v;
10     } else if (n == 2) {
11         buf[0] = (uint8_t)(0x40 | ((v >> 8) & 0x3F));
12         buf[1] = (uint8_t)v;
13     } else if (n == 4) {
14         buf[0] = (uint8_t)(0x80 | ((v >> 24) & 0x3F));
15         buf[1] = (uint8_t)(v >> 16);
16         buf[2] = (uint8_t)(v >>  8);
17         buf[3] = (uint8_t)v;
18     } else {
19         buf[0] = (uint8_t)(0xC0 | ((v >> 56) & 0x3F));
20         buf[1] = (uint8_t)(v >> 48);
21         buf[2] = (uint8_t)(v >> 40);
22         buf[3] = (uint8_t)(v >> 32);
23         buf[4] = (uint8_t)(v >> 24);
24         buf[5] = (uint8_t)(v >> 16);
25         buf[6] = (uint8_t)(v >>  8);
26         buf[7] = (uint8_t)v;
27     }
28 }
29 
ossl_quic_vlint_encode(uint8_t * buf,uint64_t v)30 void ossl_quic_vlint_encode(uint8_t *buf, uint64_t v)
31 {
32     ossl_quic_vlint_encode_n(buf, v, ossl_quic_vlint_encode_len(v));
33 }
34 
ossl_quic_vlint_decode_unchecked(const unsigned char * buf)35 uint64_t ossl_quic_vlint_decode_unchecked(const unsigned char *buf)
36 {
37     uint8_t first_byte = buf[0];
38     size_t sz = ossl_quic_vlint_decode_len(first_byte);
39 
40     if (sz == 1)
41         return first_byte & 0x3F;
42 
43     if (sz == 2)
44         return ((uint64_t)(first_byte & 0x3F) << 8)
45              | buf[1];
46 
47     if (sz == 4)
48         return ((uint64_t)(first_byte & 0x3F) << 24)
49              | ((uint64_t)buf[1] << 16)
50              | ((uint64_t)buf[2] <<  8)
51              |  buf[3];
52 
53     return ((uint64_t)(first_byte & 0x3F) << 56)
54          | ((uint64_t)buf[1] << 48)
55          | ((uint64_t)buf[2] << 40)
56          | ((uint64_t)buf[3] << 32)
57          | ((uint64_t)buf[4] << 24)
58          | ((uint64_t)buf[5] << 16)
59          | ((uint64_t)buf[6] <<  8)
60          |  buf[7];
61 }
62 
ossl_quic_vlint_decode(const unsigned char * buf,size_t buf_len,uint64_t * v)63 int ossl_quic_vlint_decode(const unsigned char *buf, size_t buf_len, uint64_t *v)
64 {
65     size_t dec_len;
66     uint64_t x;
67 
68     if (buf_len < 1)
69         return 0;
70 
71     dec_len = ossl_quic_vlint_decode_len(buf[0]);
72     if (buf_len < dec_len)
73         return 0;
74 
75     x = ossl_quic_vlint_decode_unchecked(buf);
76 
77     *v = x;
78     return dec_len;
79 }
80 
81 #endif
82