Branch data Line data Source code
1 : : /* ====================================================================
2 : : * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
3 : : *
4 : : * Redistribution and use in source and binary forms, with or without
5 : : * modification, are permitted provided that the following conditions
6 : : * are met:
7 : : *
8 : : * 1. Redistributions of source code must retain the above copyright
9 : : * notice, this list of conditions and the following disclaimer.
10 : : *
11 : : * 2. Redistributions in binary form must reproduce the above copyright
12 : : * notice, this list of conditions and the following disclaimer in
13 : : * the documentation and/or other materials provided with the
14 : : * distribution.
15 : : *
16 : : * 3. All advertising materials mentioning features or use of this
17 : : * software must display the following acknowledgment:
18 : : * "This product includes software developed by the OpenSSL Project
19 : : * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 : : *
21 : : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 : : * endorse or promote products derived from this software without
23 : : * prior written permission. For written permission, please contact
24 : : * licensing@OpenSSL.org.
25 : : *
26 : : * 5. Products derived from this software may not be called "OpenSSL"
27 : : * nor may "OpenSSL" appear in their names without prior written
28 : : * permission of the OpenSSL Project.
29 : : *
30 : : * 6. Redistributions of any form whatsoever must retain the following
31 : : * acknowledgment:
32 : : * "This product includes software developed by the OpenSSL Project
33 : : * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 : : *
35 : : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 : : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 : : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 : : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 : : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 : : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 : : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 : : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 : : * OF THE POSSIBILITY OF SUCH DAMAGE.
47 : : * ====================================================================
48 : : */
49 : :
50 : : #include <openssl/opensslconf.h>
51 : :
52 : : #include <stdio.h>
53 : : #include <string.h>
54 : : #include <openssl/engine.h>
55 : : #include <openssl/rand.h>
56 : : #include <openssl/err.h>
57 : :
58 : : #if (defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
59 : : defined(__x86_64) || defined(__x86_64__) || \
60 : : defined(_M_AMD64) || defined (_M_X64)) && defined(OPENSSL_CPUID_OBJ)
61 : :
62 : : size_t OPENSSL_ia32_rdrand(void);
63 : :
64 : 0 : static int get_random_bytes (unsigned char *buf, int num)
65 : : {
66 : : size_t rnd;
67 : :
68 [ # # ]: 0 : while (num>=(int)sizeof(size_t)) {
69 [ # # ]: 0 : if ((rnd = OPENSSL_ia32_rdrand()) == 0) return 0;
70 : :
71 : 0 : *((size_t *)buf) = rnd;
72 : 0 : buf += sizeof(size_t);
73 : 0 : num -= sizeof(size_t);
74 : : }
75 [ # # ]: 0 : if (num) {
76 [ # # ]: 0 : if ((rnd = OPENSSL_ia32_rdrand()) == 0) return 0;
77 : :
78 : 0 : memcpy (buf,&rnd,num);
79 : : }
80 : :
81 : : return 1;
82 : : }
83 : :
84 : 0 : static int random_status (void)
85 : 0 : { return 1; }
86 : :
87 : : static RAND_METHOD rdrand_meth =
88 : : {
89 : : NULL, /* seed */
90 : : get_random_bytes,
91 : : NULL, /* cleanup */
92 : : NULL, /* add */
93 : : get_random_bytes,
94 : : random_status,
95 : : };
96 : :
97 : 0 : static int rdrand_init(ENGINE *e)
98 : 0 : { return 1; }
99 : :
100 : : static const char *engine_e_rdrand_id = "rdrand";
101 : : static const char *engine_e_rdrand_name = "Intel RDRAND engine";
102 : :
103 : 728 : static int bind_helper(ENGINE *e)
104 : : {
105 [ + - + - ]: 1456 : if (!ENGINE_set_id(e, engine_e_rdrand_id) ||
106 [ + - ]: 1456 : !ENGINE_set_name(e, engine_e_rdrand_name) ||
107 [ + - ]: 1456 : !ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL) ||
108 [ - + ]: 1456 : !ENGINE_set_init_function(e, rdrand_init) ||
109 : 728 : !ENGINE_set_RAND(e, &rdrand_meth) )
110 : : return 0;
111 : :
112 : : return 1;
113 : : }
114 : :
115 : 728 : static ENGINE *ENGINE_rdrand(void)
116 : : {
117 : 728 : ENGINE *ret = ENGINE_new();
118 [ + - ]: 728 : if(!ret)
119 : : return NULL;
120 [ - + ]: 728 : if(!bind_helper(ret))
121 : : {
122 : 0 : ENGINE_free(ret);
123 : 0 : return NULL;
124 : : }
125 : : return ret;
126 : : }
127 : :
128 : 728 : void ENGINE_load_rdrand (void)
129 : : {
130 : : extern unsigned int OPENSSL_ia32cap_P[];
131 : :
132 [ + - ]: 728 : if (OPENSSL_ia32cap_P[1] & (1<<(62-32)))
133 : : {
134 : 728 : ENGINE *toadd = ENGINE_rdrand();
135 [ + - ]: 728 : if(!toadd) return;
136 : 728 : ENGINE_add(toadd);
137 : 728 : ENGINE_free(toadd);
138 : 728 : ERR_clear_error();
139 : : }
140 : : }
141 : : #else
142 : : void ENGINE_load_rdrand (void) {}
143 : : #endif
|