1 /* 2 * ctr_prng.c 3 * 4 * counter mode based pseudorandom source 5 * 6 * David A. McGrew 7 * Cisco Systems, Inc. 8 */ 9 /* 10 * 11 * Copyright(c) 2001-2006 Cisco Systems, Inc. 12 * All rights reserved. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 18 * Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 21 * Redistributions in binary form must reproduce the above 22 * copyright notice, this list of conditions and the following 23 * disclaimer in the documentation and/or other materials provided 24 * with the distribution. 25 * 26 * Neither the name of the Cisco Systems, Inc. nor the names of its 27 * contributors may be used to endorse or promote products derived 28 * from this software without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 33 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 34 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 35 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 37 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 41 * OF THE POSSIBILITY OF SUCH DAMAGE. 42 * 43 */ 44 45 46 #include "prng.h" 47 48 /* single, global prng structure */ 49 50 ctr_prng_t ctr_prng; 51 52 err_status_t 53 ctr_prng_init(rand_source_func_t random_source) { 54 uint8_t tmp_key[32]; 55 err_status_t status; 56 57 /* initialize output count to zero */ 58 ctr_prng.octet_count = 0; 59 60 /* set random source */ 61 ctr_prng.rand = random_source; 62 63 /* initialize secret key from random source */ 64 status = random_source(tmp_key, 32); 65 if (status) 66 return status; 67 68 /* initialize aes ctr context with random key */ 69 status = aes_icm_context_init(&ctr_prng.state, tmp_key); 70 if (status) 71 return status; 72 73 return err_status_ok; 74 } 75 76 err_status_t 77 ctr_prng_get_octet_string(void *dest, uint32_t len) { 78 err_status_t status; 79 80 /* 81 * if we need to re-initialize the prng, do so now 82 * 83 * avoid 32-bit overflows by subtracting instead of adding 84 */ 85 if (ctr_prng.octet_count > MAX_PRNG_OUT_LEN - len) { 86 status = ctr_prng_init(ctr_prng.rand); 87 if (status) 88 return status; 89 } 90 ctr_prng.octet_count += len; 91 92 /* 93 * write prng output 94 */ 95 status = aes_icm_output(&ctr_prng.state, (uint8_t*)dest, len); 96 if (status) 97 return status; 98 99 return err_status_ok; 100 } 101 102 err_status_t 103 ctr_prng_deinit(void) { 104 105 /* nothing */ 106 107 return err_status_ok; 108 } 109