CyaSSL is an SSL library for devices like mbed.

Dependents:   cyassl-client Sync

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers random.c Source File

random.c

00001 /* random.c
00002  *
00003  * Copyright (C) 2006-2009 Sawtooth Consulting Ltd.
00004  *
00005  * This file is part of CyaSSL.
00006  *
00007  * CyaSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * CyaSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00020  */
00021 
00022 
00023 /* on HPUX 11 you may need to install /dev/random see
00024    http://h20293.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=KRNG11I
00025 
00026 */
00027 
00028 #include "random.h"
00029 #include "error.h"
00030 
00031 
00032 #if defined(USE_WINDOWS_API)
00033     #define _WIN32_WINNT 0x0400
00034     #include <windows.h>
00035     #include <wincrypt.h>
00036 #else
00037     #ifndef NO_DEV_RANDOM
00038         #include <fcntl.h>
00039         #include <unistd.h>
00040     #else
00041         /* include headers that may be needed to get good seed */
00042     #endif
00043 #endif /* USE_WINDOWS_API */
00044 
00045 
00046 
00047 /* Get seed and key cipher */
00048 int InitRng(RNG* rng)
00049 {
00050     byte key[32];
00051     byte junk[256];
00052 
00053     int  ret = GenerateSeed(&rng->seed, key, sizeof(key));
00054 
00055     if (ret == 0) {
00056         Arc4SetKey(&rng->cipher, key, sizeof(key));
00057         RNG_GenerateBlock(rng, junk, sizeof(junk));  /* rid initial state */
00058     }
00059 
00060     return ret;
00061 }
00062 
00063 
00064 /* place a generated block in output */
00065 void RNG_GenerateBlock(RNG* rng, byte* output, word32 sz)
00066 {
00067     XMEMSET(output, 0, sz);
00068     Arc4Process(&rng->cipher, output, output, sz);
00069 }
00070 
00071 
00072 byte RNG_GenerateByte(RNG* rng)
00073 {
00074     byte b;
00075     RNG_GenerateBlock(rng, &b, 1);
00076 
00077     return b;
00078 }
00079 
00080 
00081 #if defined(USE_WINDOWS_API)
00082 
00083 
00084 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
00085 {
00086     if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL,
00087                             CRYPT_VERIFYCONTEXT))
00088         return WINCRYPT_E;
00089 
00090     if (!CryptGenRandom(os->handle, sz, output))
00091         return CRYPTGEN_E;
00092 
00093     CryptReleaseContext(os->handle, 0);
00094 
00095     return 0;
00096 }
00097 
00098 
00099 #elif defined(THREADX)
00100 
00101 #include "rtprand.h"   /* rtp_rand () */
00102 #include "rtptime.h"   /* rtp_get_system_msec() */
00103 
00104 
00105 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
00106 {
00107     int i;
00108     rtp_srand(rtp_get_system_msec());
00109 
00110     for (i = 0; i < sz; i++ ) {
00111         output[i] = rtp_rand() % 256;
00112         if ( (i % 8) == 7)
00113             rtp_srand(rtp_get_system_msec());
00114     }
00115 
00116     return 0;
00117 }
00118 
00119 
00120 #elif defined(MICRIUM)
00121 
00122 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
00123 {
00124     #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
00125         NetSecure_InitSeed(output, sz);
00126     #endif
00127     return 0;
00128 }
00129 
00130 
00131 #elif defined(MBED)
00132 
00133 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
00134 {
00135     int i;
00136     
00137     for (i = 0; i < sz; i++)
00138         output[i] = i;
00139 
00140     return 0;
00141 }
00142 
00143 
00144 #elif defined(NO_DEV_RANDOM)
00145 
00146 #error "you need to write an os specific GenerateSeed() here"
00147 
00148 
00149 #else /* !USE_WINDOWS_API && !THREADX && !MICRIUM && !NO_DEV_RANDOM */
00150 
00151 
00152 /* may block */
00153 int GenerateSeed(OS_Seed* os, byte* output, word32 sz)
00154 {
00155     os->fd = open("/dev/urandom",O_RDONLY);
00156     if (os->fd == -1) {
00157         /* may still have /dev/random */
00158         os->fd = open("/dev/random",O_RDONLY);
00159         if (os->fd == -1)
00160             return OPEN_RAN_E;
00161     }
00162 
00163     while (sz) {
00164         int len = read(os->fd, output, sz);
00165         if (len == -1) 
00166             return READ_RAN_E;
00167 
00168         sz     -= len;
00169         output += len;
00170 
00171         if (sz)
00172 #ifdef BLOCKING
00173             sleep(0);             /* context switch */
00174 #else
00175             return RAN_BLOCK_E;
00176 #endif
00177     }
00178     close(os->fd);
00179 
00180     return 0;
00181 }
00182 
00183 #endif /* USE_WINDOWS_API */
00184