1258945Sroberto/* 2258945Sroberto * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") 3258945Sroberto * Copyright (C) 1999-2001 Internet Software Consortium. 4258945Sroberto * 5258945Sroberto * Permission to use, copy, modify, and/or distribute this software for any 6258945Sroberto * purpose with or without fee is hereby granted, provided that the above 7258945Sroberto * copyright notice and this permission notice appear in all copies. 8258945Sroberto * 9258945Sroberto * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10258945Sroberto * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11258945Sroberto * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12258945Sroberto * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13258945Sroberto * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14258945Sroberto * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15258945Sroberto * PERFORMANCE OF THIS SOFTWARE. 16258945Sroberto */ 17258945Sroberto 18258945Sroberto/* $Id: lfsr.h,v 1.17 2007/06/19 23:47:18 tbox Exp $ */ 19258945Sroberto 20258945Sroberto#ifndef ISC_LFSR_H 21258945Sroberto#define ISC_LFSR_H 1 22258945Sroberto 23258945Sroberto/*! \file isc/lfsr.h */ 24258945Sroberto 25258945Sroberto#include <isc/lang.h> 26258945Sroberto#include <isc/types.h> 27258945Sroberto 28258945Srobertotypedef struct isc_lfsr isc_lfsr_t; 29258945Sroberto 30258945Sroberto/*% 31258945Sroberto * This function is called when reseeding is needed. It is allowed to 32258945Sroberto * modify any state in the LFSR in any way it sees fit OTHER THAN "bits". 33258945Sroberto * 34258945Sroberto * It MUST set "count" to a new value or the lfsr will never reseed again. 35258945Sroberto * 36258945Sroberto * Also, a reseed will never occur in the middle of an extraction. This 37258945Sroberto * is purely an optimization, and is probably what one would want. 38258945Sroberto */ 39258945Srobertotypedef void (*isc_lfsrreseed_t)(isc_lfsr_t *, void *); 40258945Sroberto 41258945Sroberto/*% 42258945Sroberto * The members of this structure can be used by the application, but care 43258945Sroberto * needs to be taken to not change state once the lfsr is in operation. 44258945Sroberto */ 45258945Srobertostruct isc_lfsr { 46258945Sroberto isc_uint32_t state; /*%< previous state */ 47258945Sroberto unsigned int bits; /*%< length */ 48258945Sroberto isc_uint32_t tap; /*%< bit taps */ 49258945Sroberto unsigned int count; /*%< reseed count (in BITS!) */ 50258945Sroberto isc_lfsrreseed_t reseed; /*%< reseed function */ 51258945Sroberto void *arg; /*%< reseed function argument */ 52258945Sroberto}; 53258945Sroberto 54258945SrobertoISC_LANG_BEGINDECLS 55258945Sroberto 56258945Sroberto 57258945Srobertovoid 58258945Srobertoisc_lfsr_init(isc_lfsr_t *lfsr, isc_uint32_t state, unsigned int bits, 59258945Sroberto isc_uint32_t tap, unsigned int count, 60258945Sroberto isc_lfsrreseed_t reseed, void *arg); 61258945Sroberto/*%< 62258945Sroberto * Initialize an LFSR. 63258945Sroberto * 64258945Sroberto * Note: 65258945Sroberto * 66258945Sroberto *\li Putting untrusted values into this function will cause the LFSR to 67258945Sroberto * generate (perhaps) non-maximal length sequences. 68258945Sroberto * 69258945Sroberto * Requires: 70258945Sroberto * 71258945Sroberto *\li lfsr != NULL 72258945Sroberto * 73258945Sroberto *\li 8 <= bits <= 32 74258945Sroberto * 75258945Sroberto *\li tap != 0 76258945Sroberto */ 77258945Sroberto 78258945Srobertovoid 79258945Srobertoisc_lfsr_generate(isc_lfsr_t *lfsr, void *data, unsigned int count); 80258945Sroberto/*%< 81258945Sroberto * Returns "count" bytes of data from the LFSR. 82258945Sroberto * 83258945Sroberto * Requires: 84258945Sroberto * 85258945Sroberto *\li lfsr be valid. 86258945Sroberto * 87258945Sroberto *\li data != NULL. 88258945Sroberto * 89258945Sroberto *\li count > 0. 90258945Sroberto */ 91258945Sroberto 92258945Srobertovoid 93258945Srobertoisc_lfsr_skip(isc_lfsr_t *lfsr, unsigned int skip); 94258945Sroberto/*%< 95258945Sroberto * Skip "skip" states. 96258945Sroberto * 97258945Sroberto * Requires: 98258945Sroberto * 99258945Sroberto *\li lfsr be valid. 100258945Sroberto */ 101258945Sroberto 102258945Srobertoisc_uint32_t 103258945Srobertoisc_lfsr_generate32(isc_lfsr_t *lfsr1, isc_lfsr_t *lfsr2); 104258945Sroberto/*%< 105258945Sroberto * Given two LFSRs, use the current state from each to skip entries in the 106258945Sroberto * other. The next states are then xor'd together and returned. 107258945Sroberto * 108258945Sroberto * WARNING: 109258945Sroberto * 110258945Sroberto *\li This function is used only for very, very low security data, such 111258945Sroberto * as DNS message IDs where it is desired to have an unpredictable 112258945Sroberto * stream of bytes that are harder to predict than a simple flooding 113258945Sroberto * attack. 114258945Sroberto * 115258945Sroberto * Notes: 116258945Sroberto * 117258945Sroberto *\li Since the current state from each of the LFSRs is used to skip 118258945Sroberto * state in the other, it is important that no state be leaked 119258945Sroberto * from either LFSR. 120258945Sroberto * 121258945Sroberto * Requires: 122258945Sroberto * 123258945Sroberto *\li lfsr1 and lfsr2 be valid. 124258945Sroberto * 125258945Sroberto *\li 1 <= skipbits <= 31 126258945Sroberto */ 127258945Sroberto 128258945SrobertoISC_LANG_ENDDECLS 129258945Sroberto 130258945Sroberto#endif /* ISC_LFSR_H */ 131