~ubuntu-branches/ubuntu/utopic/dropbear/utopic-proposed

« back to all changes in this revision

Viewing changes to libtomcrypt/rng_get_bytes.c

  • Committer: Bazaar Package Importer
  • Author(s): Matt Johnston
  • Date: 2005-12-08 19:20:21 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051208192021-nyp9rwnt77nsg6ty
Tags: 0.47-1
* New upstream release.
* SECURITY: Fix incorrect buffer sizing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
2
 
 *
3
 
 * LibTomCrypt is a library that provides various cryptographic
4
 
 * algorithms in a highly modular and flexible manner.
5
 
 *
6
 
 * The library is free for all purposes without any express
7
 
 * guarantee it works.
8
 
 *
9
 
 * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
10
 
 */
11
 
/* portable way to get secure random bits to feed a PRNG */
12
 
#include "mycrypt.h"
13
 
 
14
 
#ifdef DEVRANDOM
15
 
/* on *NIX read /dev/random */
16
 
static unsigned long rng_nix(unsigned char *buf, unsigned long len, 
17
 
                             void (*callback)(void))
18
 
{
19
 
#ifdef NO_FILE
20
 
    return 0;
21
 
#else
22
 
    FILE *f;
23
 
    unsigned long x;
24
 
#ifdef TRY_URANDOM_FIRST
25
 
    f = fopen("/dev/urandom", "rb");
26
 
    if (f == NULL)
27
 
#endif /* TRY_URANDOM_FIRST */
28
 
       f = fopen("/dev/random", "rb");
29
 
 
30
 
    if (f == NULL) {
31
 
       return 0;
32
 
    }
33
 
    
34
 
    /* disable buffering */
35
 
    if (setvbuf(f, NULL, _IONBF, 0) != 0) {
36
 
       fclose(f);
37
 
       return 0;
38
 
    }   
39
 
 
40
 
    x = (unsigned long)fread(buf, 1, (size_t)len, f);
41
 
    fclose(f);
42
 
    return x;
43
 
#endif /* NO_FILE */
44
 
}
45
 
 
46
 
#endif /* DEVRANDOM */
47
 
 
48
 
/* on ANSI C platforms with 100 < CLOCKS_PER_SEC < 10000 */
49
 
#if defined(CLOCKS_PER_SEC)
50
 
 
51
 
#define ANSI_RNG
52
 
 
53
 
static unsigned long rng_ansic(unsigned char *buf, unsigned long len, 
54
 
                               void (*callback)(void))
55
 
{
56
 
   clock_t t1;
57
 
   int l, acc, bits, a, b;
58
 
 
59
 
   if (XCLOCKS_PER_SEC < 100 || XCLOCKS_PER_SEC > 10000) {
60
 
      return 0;
61
 
   }
62
 
 
63
 
   l = len;
64
 
   bits = 8;
65
 
   acc  = a = b = 0;
66
 
   while (len--) {
67
 
       if (callback != NULL) callback();
68
 
       while (bits--) {
69
 
          do {
70
 
             t1 = XCLOCK(); while (t1 == XCLOCK()) a ^= 1;
71
 
             t1 = XCLOCK(); while (t1 == XCLOCK()) b ^= 1;
72
 
          } while (a == b);
73
 
          acc = (acc << 1) | a;
74
 
       }
75
 
       *buf++ = acc; 
76
 
       acc  = 0;
77
 
       bits = 8;
78
 
   }
79
 
   acc = bits = a = b = 0;
80
 
   return l;
81
 
}
82
 
 
83
 
#endif 
84
 
 
85
 
/* Try the Microsoft CSP */
86
 
#ifdef WIN32
87
 
#define _WIN32_WINNT 0x0400
88
 
#include <windows.h>
89
 
#include <wincrypt.h>
90
 
 
91
 
static unsigned long rng_win32(unsigned char *buf, unsigned long len, 
92
 
                               void (*callback)(void))
93
 
{
94
 
   HCRYPTPROV hProv = 0;
95
 
   if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, 
96
 
                            (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) && 
97
 
       !CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, 
98
 
                            CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET))
99
 
      return 0;
100
 
 
101
 
   if (CryptGenRandom(hProv, len, buf) == TRUE) {
102
 
      CryptReleaseContext(hProv, 0);
103
 
      return len;
104
 
   } else {
105
 
      CryptReleaseContext(hProv, 0);
106
 
      return 0;
107
 
   }
108
 
}
109
 
 
110
 
#endif /* WIN32 */
111
 
 
112
 
unsigned long rng_get_bytes(unsigned char *buf, unsigned long len, 
113
 
                            void (*callback)(void))
114
 
{
115
 
   unsigned long x;
116
 
 
117
 
   _ARGCHK(buf != NULL);
118
 
 
119
 
#if defined(DEVRANDOM)
120
 
   x = rng_nix(buf, len, callback);   if (x != 0) { return x; }
121
 
#endif
122
 
#ifdef WIN32
123
 
   x = rng_win32(buf, len, callback); if (x != 0) { return x; }
124
 
#endif
125
 
#ifdef ANSI_RNG
126
 
   x = rng_ansic(buf, len, callback); if (x != 0) { return x; }
127
 
#endif
128
 
   return 0;
129
 
}