xref: /netbsd-src/external/mpl/dhcp/bind/dist/lib/isc/include/isc/lfsr.h (revision 4afad4b7fa6d4a0d3dedf41d1587a7250710ae54)
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 
26 typedef 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  */
37 typedef 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  */
43 struct 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 
52 ISC_LANG_BEGINDECLS
53 
54 void
55 isc_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 
74 void
75 isc_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 
88 void
89 isc_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 
98 uint32_t
99 isc_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 
124 ISC_LANG_ENDDECLS
125 
126 #endif /* ISC_LFSR_H */
127