/src/openssl/crypto/engine/eng_rdrand.c
Line | Count | Source (jump to first uncovered line) |
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 | | static int get_random_bytes(unsigned char *buf, int num) |
65 | 0 | { |
66 | 0 | size_t rnd; |
67 | |
|
68 | 0 | while (num >= (int)sizeof(size_t)) { |
69 | 0 | if ((rnd = OPENSSL_ia32_rdrand()) == 0) |
70 | 0 | return 0; |
71 | | |
72 | 0 | *((size_t *)buf) = rnd; |
73 | 0 | buf += sizeof(size_t); |
74 | 0 | num -= sizeof(size_t); |
75 | 0 | } |
76 | 0 | if (num) { |
77 | 0 | if ((rnd = OPENSSL_ia32_rdrand()) == 0) |
78 | 0 | return 0; |
79 | | |
80 | 0 | memcpy(buf, &rnd, num); |
81 | 0 | } |
82 | | |
83 | 0 | return 1; |
84 | 0 | } |
85 | | |
86 | | static int random_status(void) |
87 | 0 | { |
88 | 0 | return 1; |
89 | 0 | } |
90 | | |
91 | | static RAND_METHOD rdrand_meth = { |
92 | | NULL, /* seed */ |
93 | | get_random_bytes, |
94 | | NULL, /* cleanup */ |
95 | | NULL, /* add */ |
96 | | get_random_bytes, |
97 | | random_status, |
98 | | }; |
99 | | |
100 | | static int rdrand_init(ENGINE *e) |
101 | 0 | { |
102 | 0 | return 1; |
103 | 0 | } |
104 | | |
105 | | static const char *engine_e_rdrand_id = "rdrand"; |
106 | | static const char *engine_e_rdrand_name = "Intel RDRAND engine"; |
107 | | |
108 | | static int bind_helper(ENGINE *e) |
109 | 19 | { |
110 | 19 | if (!ENGINE_set_id(e, engine_e_rdrand_id) || |
111 | 19 | !ENGINE_set_name(e, engine_e_rdrand_name) || |
112 | 19 | !ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL) || |
113 | 19 | !ENGINE_set_init_function(e, rdrand_init) || |
114 | 19 | !ENGINE_set_RAND(e, &rdrand_meth)) |
115 | 0 | return 0; |
116 | | |
117 | 19 | return 1; |
118 | 19 | } |
119 | | |
120 | | static ENGINE *ENGINE_rdrand(void) |
121 | 19 | { |
122 | 19 | ENGINE *ret = ENGINE_new(); |
123 | 19 | if (!ret) |
124 | 0 | return NULL; |
125 | 19 | if (!bind_helper(ret)) { |
126 | 0 | ENGINE_free(ret); |
127 | 0 | return NULL; |
128 | 0 | } |
129 | 19 | return ret; |
130 | 19 | } |
131 | | |
132 | | void ENGINE_load_rdrand(void) |
133 | 19 | { |
134 | 19 | extern unsigned int OPENSSL_ia32cap_P[]; |
135 | | |
136 | 19 | if (OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) { |
137 | 19 | ENGINE *toadd = ENGINE_rdrand(); |
138 | 19 | if (!toadd) |
139 | 0 | return; |
140 | 19 | ENGINE_add(toadd); |
141 | 19 | ENGINE_free(toadd); |
142 | 19 | ERR_clear_error(); |
143 | 19 | } |
144 | 19 | } |
145 | | #else |
146 | | void ENGINE_load_rdrand(void) |
147 | | { |
148 | | } |
149 | | #endif |