2002-05-15 Radek Doulik <rodo@ximian.com>
[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 void 
28 ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_GetBytes (MonoObject *self, MonoArray *arry)
29 {
30     guint32 len;
31     gint file;
32     gint err;
33     guchar *buf;
34
35     len = mono_array_length(arry);
36     buf = mono_array_addr(arry, guchar, 0);
37
38     file = open(NAME_DEV_RANDOM, O_RDONLY);
39
40     if (file < 0) {
41         g_warning("Entropy problem! Can't open %s", NAME_DEV_RANDOM);
42
43         /* This needs to be a crypto exception */
44         mono_raise_exception(mono_get_exception_not_implemented());
45     }
46
47     /* A little optimization.... */
48     err = read(file, buf, len);
49
50     if (err < 0) {
51         g_warning("Entropy error! Error in read.");
52         mono_raise_exception(mono_get_exception_not_implemented());
53     }
54
55     if (err != len) {
56         g_warning("Entropy error! Length != bytes read");
57         mono_raise_exception(mono_get_exception_not_implemented());
58     }
59
60     close(file);
61 }
62
63 void 
64 ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_GetNonZeroBytes (MonoObject *self, MonoArray *arry)
65 {
66     guint32 len;
67     gint file, i;
68     gint err;
69     guchar byte = 0;
70
71     len = mono_array_length(arry);
72
73     file = open(NAME_DEV_RANDOM, O_RDONLY);
74
75     if (file < 0) {
76         g_warning("Entropy problem! Can't open %s", NAME_DEV_RANDOM);
77
78         /* This needs to be a crypto exception */
79         mono_raise_exception(mono_get_exception_not_implemented());
80     }
81
82     for (i = 0; i < len; i++) {
83
84         do {
85             err = read(file, &byte, 1);
86         } while (byte == 0);
87
88         if (err < 0) {
89             g_warning("Entropy error! Error in read.");
90             mono_raise_exception(mono_get_exception_not_implemented());
91         }
92
93         mono_array_set(arry, guchar, i, byte);
94     }
95
96     close(file);
97 }
98
99 /* This needs to change when I do the Win32 support... */
100 #else
101 #warning "No Entropy Source Found"
102 void ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_GetBytes(MonoObject *self, MonoArray *arry)
103 {
104     g_warning("0K problem. We have no entropy. Badness will occur.");
105     mono_raise_exception(mono_get_exception_not_implemented());
106 }
107
108 void ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_GetNonZeroBytes(MonoObject *self, MonoArray *arry)
109 {
110     g_warning("0K problem. We have no entropy. Badness will occur.");
111     mono_raise_exception(mono_get_exception_not_implemented());
112 }
113
114 #endif