* test-9.il: New test, test instaniating a class
[mono.git] / mono / metadata / rand.c
1 /*
2  * rand.c: System.Security.Cryptography.RNGCryptoServiceProvider support
3  *
4  * Author:
5  *      Mark Crichton (crichton@gimp.org)
6  *
7  * (C) 2001 Ximian, Inc.
8  *
9  */
10
11
12 /* Ok, the exception handling is bogus.  I need to work on that */
13
14 #include <config.h>
15 #include <glib.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <fcntl.h>
19 #include <unistd.h>
20
21 #include <mono/metadata/object.h>
22 #include <mono/metadata/rand.h>
23 #include <mono/metadata/exception.h>
24
25 #if defined (NAME_DEV_RANDOM) && defined (HAVE_CRYPT_RNG)
26
27 #ifndef NAME_DEV_URANDOM
28 #define NAME_DEV_URANDOM "/dev/urandom"
29 #endif
30
31 void 
32 ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_InternalGetBytes (MonoObject *self, MonoArray *arry)
33 {
34     guint32 len;
35     gint file;
36     gint err;
37     gint count;
38     guchar *buf;
39
40     len = mono_array_length(arry);
41     buf = mono_array_addr(arry, guchar, 0);
42
43     file = open (NAME_DEV_URANDOM, O_RDONLY);
44
45     if (file < 0)
46             file = open (NAME_DEV_RANDOM, O_RDONLY);
47
48     if (file < 0) {
49         g_warning ("Entropy problem! Can't open %s or %s", NAME_DEV_URANDOM, NAME_DEV_RANDOM);
50
51         /* This needs to be a crypto exception */
52         mono_raise_exception(mono_get_exception_not_implemented());
53     }
54
55     /* Read until the buffer is filled. This may block if using NAME_DEV_RANDOM. */
56     count = 0;
57     do {
58             err = read(file, buf + count, len - count);
59             count += err;
60     } while (err >= 0 && count < len);
61
62     if (err < 0) {
63         g_warning("Entropy error! Error in read.");
64         mono_raise_exception(mono_get_exception_not_implemented());
65     }
66
67     close(file);
68 }
69
70 void 
71 ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_InternalGetNonZeroBytes (MonoObject *self, MonoArray *arry)
72 {
73     guint32 len;
74     gint file, i;
75     gint err;
76     guchar byte = 0;
77
78     len = mono_array_length(arry);
79
80     file = open(NAME_DEV_RANDOM, O_RDONLY);
81
82     if (file < 0) {
83         g_warning("Entropy problem! Can't open %s", NAME_DEV_RANDOM);
84
85         /* This needs to be a crypto exception */
86         mono_raise_exception(mono_get_exception_not_implemented());
87     }
88
89     for (i = 0; i < len; i++) {
90
91         do {
92             err = read(file, &byte, 1);
93         } while (byte == 0);
94
95         if (err < 0) {
96             g_warning("Entropy error! Error in read.");
97             mono_raise_exception(mono_get_exception_not_implemented());
98         }
99
100         mono_array_set(arry, guchar, i, byte);
101     }
102
103     close(file);
104 }
105
106 /* This needs to change when I do the Win32 support... */
107 #else
108 #warning "No Entropy Source Found"
109 void ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_InternalGetBytes(MonoObject *self, MonoArray *arry)
110 {
111     g_warning("0K problem. We have no entropy. Badness will occur.");
112     mono_raise_exception(mono_get_exception_not_implemented());
113 }
114
115 void ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_InternalGetNonZeroBytes(MonoObject *self, MonoArray *arry)
116 {
117     g_warning("0K problem. We have no entropy. Badness will occur.");
118     mono_raise_exception(mono_get_exception_not_implemented());
119 }
120
121 #endif