1/* $NetBSD: lfsr.h,v 1.1 2024/02/18 20:57:53 christos Exp $ */ 2 3/* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16#ifndef ISC_LFSR_H 17#define ISC_LFSR_H 1 18 19/*! \file isc/lfsr.h */ 20 21#include <inttypes.h> 22 23#include <isc/lang.h> 24#include <isc/types.h> 25 26typedef struct isc_lfsr isc_lfsr_t; 27 28/*% 29 * This function is called when reseeding is needed. It is allowed to 30 * modify any state in the LFSR in any way it sees fit OTHER THAN "bits". 31 * 32 * It MUST set "count" to a new value or the lfsr will never reseed again. 33 * 34 * Also, a reseed will never occur in the middle of an extraction. This 35 * is purely an optimization, and is probably what one would want. 36 */ 37typedef void (*isc_lfsrreseed_t)(isc_lfsr_t *, void *); 38 39/*% 40 * The members of this structure can be used by the application, but care 41 * needs to be taken to not change state once the lfsr is in operation. 42 */ 43struct isc_lfsr { 44 uint32_t state; /*%< previous state */ 45 unsigned int bits; /*%< length */ 46 uint32_t tap; /*%< bit taps */ 47 unsigned int count; /*%< reseed count (in BITS!) */ 48 isc_lfsrreseed_t reseed; /*%< reseed function */ 49 void *arg; /*%< reseed function argument */ 50}; 51 52ISC_LANG_BEGINDECLS 53 54void 55isc_lfsr_init(isc_lfsr_t *lfsr, uint32_t state, unsigned int bits, uint32_t tap, 56 unsigned int count, isc_lfsrreseed_t reseed, void *arg); 57/*%< 58 * Initialize an LFSR. 59 * 60 * Note: 61 * 62 *\li Putting untrusted values into this function will cause the LFSR to 63 * generate (perhaps) non-maximal length sequences. 64 * 65 * Requires: 66 * 67 *\li lfsr != NULL 68 * 69 *\li 8 <= bits <= 32 70 * 71 *\li tap != 0 72 */ 73 74void 75isc_lfsr_generate(isc_lfsr_t *lfsr, void *data, unsigned int count); 76/*%< 77 * Returns "count" bytes of data from the LFSR. 78 * 79 * Requires: 80 * 81 *\li lfsr be valid. 82 * 83 *\li data != NULL. 84 * 85 *\li count > 0. 86 */ 87 88void 89isc_lfsr_skip(isc_lfsr_t *lfsr, unsigned int skip); 90/*%< 91 * Skip "skip" states. 92 * 93 * Requires: 94 * 95 *\li lfsr be valid. 96 */ 97 98uint32_t 99isc_lfsr_generate32(isc_lfsr_t *lfsr1, isc_lfsr_t *lfsr2); 100/*%< 101 * Given two LFSRs, use the current state from each to skip entries in the 102 * other. The next states are then xor'd together and returned. 103 * 104 * WARNING: 105 * 106 *\li This function is used only for very, very low security data, such 107 * as DNS message IDs where it is desired to have an unpredictable 108 * stream of bytes that are harder to predict than a simple flooding 109 * attack. 110 * 111 * Notes: 112 * 113 *\li Since the current state from each of the LFSRs is used to skip 114 * state in the other, it is important that no state be leaked 115 * from either LFSR. 116 * 117 * Requires: 118 * 119 *\li lfsr1 and lfsr2 be valid. 120 * 121 *\li 1 <= skipbits <= 31 122 */ 123 124ISC_LANG_ENDDECLS 125 126#endif /* ISC_LFSR_H */ 127