netwerk/srtp/src/crypto/rng/prng.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/netwerk/srtp/src/crypto/rng/prng.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,180 @@
     1.4 +/*
     1.5 + * prng.c 
     1.6 + *
     1.7 + * pseudorandom source
     1.8 + *
     1.9 + * David A. McGrew
    1.10 + * Cisco Systems, Inc.
    1.11 + */
    1.12 +/*
    1.13 + *	
    1.14 + * Copyright(c) 2001-2006 Cisco Systems, Inc.
    1.15 + * All rights reserved.
    1.16 + * 
    1.17 + * Redistribution and use in source and binary forms, with or without
    1.18 + * modification, are permitted provided that the following conditions
    1.19 + * are met:
    1.20 + * 
    1.21 + *   Redistributions of source code must retain the above copyright
    1.22 + *   notice, this list of conditions and the following disclaimer.
    1.23 + * 
    1.24 + *   Redistributions in binary form must reproduce the above
    1.25 + *   copyright notice, this list of conditions and the following
    1.26 + *   disclaimer in the documentation and/or other materials provided
    1.27 + *   with the distribution.
    1.28 + * 
    1.29 + *   Neither the name of the Cisco Systems, Inc. nor the names of its
    1.30 + *   contributors may be used to endorse or promote products derived
    1.31 + *   from this software without specific prior written permission.
    1.32 + * 
    1.33 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    1.34 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    1.35 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
    1.36 + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
    1.37 + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
    1.38 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    1.39 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    1.40 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    1.41 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    1.42 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    1.43 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    1.44 + * OF THE POSSIBILITY OF SUCH DAMAGE.
    1.45 + *
    1.46 + */
    1.47 +
    1.48 +
    1.49 +#include "prng.h"
    1.50 +
    1.51 +/* single, global prng structure */
    1.52 +
    1.53 +x917_prng_t x917_prng;
    1.54 +
    1.55 +err_status_t
    1.56 +x917_prng_init(rand_source_func_t random_source) {
    1.57 +  uint8_t tmp_key[16];
    1.58 +  err_status_t status;
    1.59 +
    1.60 +  /* initialize output count to zero */
    1.61 +  x917_prng.octet_count = 0;
    1.62 +
    1.63 +  /* set random source */
    1.64 +  x917_prng.rand = random_source;
    1.65 +  
    1.66 +  /* initialize secret key from random source */
    1.67 +  status = random_source(tmp_key, 16);
    1.68 +  if (status) 
    1.69 +    return status;
    1.70 +
    1.71 +  /* expand aes key */
    1.72 +  aes_expand_encryption_key(tmp_key, 16, &x917_prng.key);
    1.73 +
    1.74 +  /* initialize prng state from random source */
    1.75 +  status = x917_prng.rand((uint8_t *)&x917_prng.state, 16);
    1.76 +  if (status) 
    1.77 +    return status;
    1.78 +
    1.79 +  return err_status_ok;
    1.80 +}
    1.81 +
    1.82 +err_status_t
    1.83 +x917_prng_get_octet_string(uint8_t *dest, uint32_t len) {
    1.84 +  uint32_t t;
    1.85 +  v128_t buffer;
    1.86 +  uint32_t i, tail_len;
    1.87 +  err_status_t status;
    1.88 +
    1.89 +  /* 
    1.90 +   * if we need to re-initialize the prng, do so now 
    1.91 +   *
    1.92 +   * avoid overflows by subtracting instead of adding
    1.93 +   */
    1.94 +  if (x917_prng.octet_count > MAX_PRNG_OUT_LEN - len) {
    1.95 +    status = x917_prng_init(x917_prng.rand);    
    1.96 +    if (status)
    1.97 +      return status;
    1.98 +  }
    1.99 +  x917_prng.octet_count += len;
   1.100 +  
   1.101 +  /* find out the time */
   1.102 +  t = (uint32_t)time(NULL);
   1.103 +  
   1.104 +  /* loop until we have output enough data */
   1.105 +  for (i=0; i < len/16; i++) {
   1.106 +    
   1.107 +    /* exor time into state */
   1.108 +    x917_prng.state.v32[0] ^= t; 
   1.109 + 
   1.110 +    /* copy state into buffer */
   1.111 +    v128_copy(&buffer, &x917_prng.state);
   1.112 +
   1.113 +    /* apply aes to buffer */
   1.114 +    aes_encrypt(&buffer, &x917_prng.key);
   1.115 +    
   1.116 +    /* write data to output */
   1.117 +    *dest++ = buffer.v8[0];
   1.118 +    *dest++ = buffer.v8[1];
   1.119 +    *dest++ = buffer.v8[2];
   1.120 +    *dest++ = buffer.v8[3];
   1.121 +    *dest++ = buffer.v8[4];
   1.122 +    *dest++ = buffer.v8[5];
   1.123 +    *dest++ = buffer.v8[6];
   1.124 +    *dest++ = buffer.v8[7];
   1.125 +    *dest++ = buffer.v8[8];
   1.126 +    *dest++ = buffer.v8[9];
   1.127 +    *dest++ = buffer.v8[10];
   1.128 +    *dest++ = buffer.v8[11];
   1.129 +    *dest++ = buffer.v8[12];
   1.130 +    *dest++ = buffer.v8[13];
   1.131 +    *dest++ = buffer.v8[14];
   1.132 +    *dest++ = buffer.v8[15];
   1.133 +
   1.134 +    /* exor time into buffer */
   1.135 +    buffer.v32[0] ^= t;
   1.136 +
   1.137 +    /* encrypt buffer */
   1.138 +    aes_encrypt(&buffer, &x917_prng.key);
   1.139 +
   1.140 +    /* copy buffer into state */
   1.141 +    v128_copy(&x917_prng.state, &buffer);
   1.142 +    
   1.143 +  }
   1.144 +  
   1.145 +  /* if we need to output any more octets, we'll do so now */
   1.146 +  tail_len = len % 16;
   1.147 +  if (tail_len) {
   1.148 +    
   1.149 +    /* exor time into state */
   1.150 +    x917_prng.state.v32[0] ^= t; 
   1.151 + 
   1.152 +    /* copy value into buffer */
   1.153 +    v128_copy(&buffer, &x917_prng.state);
   1.154 +
   1.155 +    /* apply aes to buffer */
   1.156 +    aes_encrypt(&buffer, &x917_prng.key);
   1.157 +
   1.158 +    /* write data to output */
   1.159 +    for (i=0; i < tail_len; i++) {
   1.160 +      *dest++ = buffer.v8[i];
   1.161 +    }
   1.162 +
   1.163 +    /* now update the state one more time */
   1.164 +
   1.165 +    /* exor time into buffer */
   1.166 +    buffer.v32[0] ^= t;
   1.167 +
   1.168 +    /* encrypt buffer */
   1.169 +    aes_encrypt(&buffer, &x917_prng.key);
   1.170 +
   1.171 +    /* copy buffer into state */
   1.172 +    v128_copy(&x917_prng.state, &buffer);
   1.173 +
   1.174 +  }
   1.175 +  
   1.176 +  return err_status_ok;
   1.177 +}
   1.178 +
   1.179 +err_status_t
   1.180 +x917_prng_deinit(void) {
   1.181 +  
   1.182 +  return err_status_ok;  
   1.183 +}

mercurial