1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
210c41073SDmitri Tikhonov#include <openssl/rand.h>
310c41073SDmitri Tikhonov#include <stdint.h>
410c41073SDmitri Tikhonov
510c41073SDmitri Tikhonov#include "lsquic_crand.h"
610c41073SDmitri Tikhonov
710c41073SDmitri Tikhonov
810c41073SDmitri Tikhonov#define OFF_MASK(crand_) ((sizeof((crand_)->rand_buf) * 2) - 1)
910c41073SDmitri Tikhonov
1010c41073SDmitri Tikhonov
1110c41073SDmitri Tikhonovuint8_t
1210c41073SDmitri Tikhonovlsquic_crand_get_nybble (struct crand *crand)
1310c41073SDmitri Tikhonov{
1410c41073SDmitri Tikhonov    uint8_t byte;
1510c41073SDmitri Tikhonov
1610c41073SDmitri Tikhonov    if (crand->nybble_off == 0)
1710c41073SDmitri Tikhonov        RAND_bytes(crand->rand_buf, sizeof(crand->rand_buf));
1810c41073SDmitri Tikhonov
1910c41073SDmitri Tikhonov    byte = crand->rand_buf[crand->nybble_off / 2];
2010c41073SDmitri Tikhonov    if (crand->nybble_off & 1)
2110c41073SDmitri Tikhonov        byte >>= 4;
2210c41073SDmitri Tikhonov    else
2310c41073SDmitri Tikhonov        byte &= 0xF;
2410c41073SDmitri Tikhonov    crand->nybble_off += 1;
2510c41073SDmitri Tikhonov    crand->nybble_off &= OFF_MASK(crand);
2610c41073SDmitri Tikhonov    return byte;
2710c41073SDmitri Tikhonov}
2810c41073SDmitri Tikhonov
2910c41073SDmitri Tikhonov
3010c41073SDmitri Tikhonovuint8_t
3110c41073SDmitri Tikhonovlsquic_crand_get_byte (struct crand *crand)
3210c41073SDmitri Tikhonov{
3310c41073SDmitri Tikhonov    uint8_t byte;
3410c41073SDmitri Tikhonov
3510c41073SDmitri Tikhonov    if (crand->nybble_off & 1)
3610c41073SDmitri Tikhonov        return (lsquic_crand_get_nybble(crand) << 4)
3710c41073SDmitri Tikhonov             |  lsquic_crand_get_nybble(crand);
3810c41073SDmitri Tikhonov    else
3910c41073SDmitri Tikhonov    {
4010c41073SDmitri Tikhonov        if (crand->nybble_off == 0)
4110c41073SDmitri Tikhonov            RAND_bytes(crand->rand_buf, sizeof(crand->rand_buf));
4210c41073SDmitri Tikhonov        byte = crand->rand_buf[crand->nybble_off / 2];
4310c41073SDmitri Tikhonov        crand->nybble_off += 2;
4410c41073SDmitri Tikhonov        crand->nybble_off &= OFF_MASK(crand);
4510c41073SDmitri Tikhonov        return byte;
4610c41073SDmitri Tikhonov    }
4710c41073SDmitri Tikhonov}
48