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