1/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
2#include <openssl/rand.h>
3#include <stdint.h>
4
5#include "lsquic_crand.h"
6
7
8#define OFF_MASK(crand_) ((sizeof((crand_)->rand_buf) * 2) - 1)
9
10
11uint8_t
12lsquic_crand_get_nybble (struct crand *crand)
13{
14    uint8_t byte;
15
16    if (crand->nybble_off == 0)
17        RAND_bytes(crand->rand_buf, sizeof(crand->rand_buf));
18
19    byte = crand->rand_buf[crand->nybble_off / 2];
20    if (crand->nybble_off & 1)
21        byte >>= 4;
22    else
23        byte &= 0xF;
24    crand->nybble_off += 1;
25    crand->nybble_off &= OFF_MASK(crand);
26    return byte;
27}
28
29
30uint8_t
31lsquic_crand_get_byte (struct crand *crand)
32{
33    uint8_t byte;
34
35    if (crand->nybble_off & 1)
36        return (lsquic_crand_get_nybble(crand) << 4)
37             |  lsquic_crand_get_nybble(crand);
38    else
39    {
40        if (crand->nybble_off == 0)
41            RAND_bytes(crand->rand_buf, sizeof(crand->rand_buf));
42        byte = crand->rand_buf[crand->nybble_off / 2];
43        crand->nybble_off += 2;
44        crand->nybble_off &= OFF_MASK(crand);
45        return byte;
46    }
47}
48