1 | /* Copyright (c) 2012, Oracle and/or its affiliates. |
2 | Copyright (c) 2014, 2017, MariaDB |
3 | |
4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by |
6 | the Free Software Foundation; version 2 of the License. |
7 | |
8 | This program is distributed in the hope that it will be useful, |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | GNU General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU General Public License |
14 | along with this program; if not, write to the Free Software Foundation, |
15 | 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ |
16 | |
17 | |
18 | /** |
19 | @file |
20 | |
21 | @brief |
22 | Wrapper functions for OpenSSL, YaSSL implementations. Also provides a |
23 | Compatibility layer to make available YaSSL's SHAn implementation. |
24 | */ |
25 | |
26 | #include <my_global.h> |
27 | #include <stdarg.h> |
28 | |
29 | #define HASH_SIZE (NUM > 1 ? NUM/8 : 20) |
30 | |
31 | #if defined(HAVE_YASSL) |
32 | #include "sha.hpp" |
33 | |
34 | #define xCONTEXT(x) TaoCrypt::SHA ## x |
35 | #define yCONTEXT(y) xCONTEXT(y) |
36 | #define CONTEXT yCONTEXT(NUM) |
37 | #define SHA1 SHA |
38 | |
39 | static void sha_init(CONTEXT *context) |
40 | { |
41 | context->Init(); |
42 | } |
43 | |
44 | /* |
45 | this is a variant of sha_init to be used in this file only. |
46 | does nothing for yassl, because the context's constructor was called automatically. |
47 | */ |
48 | static void sha_init_fast(CONTEXT *context) |
49 | { |
50 | } |
51 | |
52 | static void sha_input(CONTEXT *context, const uchar *buf, unsigned len) |
53 | { |
54 | context->Update((const TaoCrypt::byte *) buf, len); |
55 | } |
56 | |
57 | static void sha_result(CONTEXT *context, uchar digest[HASH_SIZE]) |
58 | { |
59 | context->Final((TaoCrypt::byte *) digest); |
60 | } |
61 | |
62 | #elif defined(HAVE_OPENSSL) |
63 | #include <openssl/sha.h> |
64 | |
65 | #define xCONTEXT(x) SHA ## x ## _CTX |
66 | #define yCONTEXT(y) xCONTEXT(y) |
67 | #define CONTEXT yCONTEXT(NUM) |
68 | #define SHA1_CTX SHA_CTX |
69 | #define SHA224_CTX SHA256_CTX |
70 | #define SHA384_CTX SHA512_CTX |
71 | |
72 | #define xSHA_Init(x) SHA ## x ## _Init |
73 | #define xSHA_Update(x) SHA ## x ## _Update |
74 | #define xSHA_Final(x) SHA ## x ## _Final |
75 | #define ySHA_Init(y) xSHA_Init(y) |
76 | #define ySHA_Update(y) xSHA_Update(y) |
77 | #define ySHA_Final(y) xSHA_Final(y) |
78 | #define SHA_Init ySHA_Init(NUM) |
79 | #define SHA_Update ySHA_Update(NUM) |
80 | #define SHA_Final ySHA_Final(NUM) |
81 | |
82 | static void sha_init(CONTEXT *context) |
83 | { |
84 | SHA_Init(context); |
85 | } |
86 | |
87 | static void sha_init_fast(CONTEXT *context) |
88 | { |
89 | sha_init(context); |
90 | } |
91 | |
92 | static void sha_input(CONTEXT *context, const uchar *buf, unsigned len) |
93 | { |
94 | SHA_Update(context, buf, len); |
95 | } |
96 | |
97 | static void sha_result(CONTEXT *context, uchar digest[HASH_SIZE]) |
98 | { |
99 | SHA_Final(digest, context); |
100 | } |
101 | |
102 | #endif /* HAVE_YASSL */ |
103 | |
104 | #define xmy_sha_multi(x) my_sha ## x ## _multi |
105 | #define xmy_sha_context_size(x) my_sha ## x ## _context_size |
106 | #define xmy_sha_init(x) my_sha ## x ## _init |
107 | #define xmy_sha_input(x) my_sha ## x ## _input |
108 | #define xmy_sha_result(x) my_sha ## x ## _result |
109 | #define xmy_sha(x) my_sha ## x |
110 | #define ymy_sha_multi(y) xmy_sha_multi(y) |
111 | #define ymy_sha_context_size(y) xmy_sha_context_size(y) |
112 | #define ymy_sha_init(y) xmy_sha_init(y) |
113 | #define ymy_sha_input(y) xmy_sha_input(y) |
114 | #define ymy_sha_result(y) xmy_sha_result(y) |
115 | #define ymy_sha(y) xmy_sha(y) |
116 | #define my_sha_multi ymy_sha_multi(NUM) |
117 | #define my_sha_context_size ymy_sha_context_size(NUM) |
118 | #define my_sha_init ymy_sha_init(NUM) |
119 | #define my_sha_input ymy_sha_input(NUM) |
120 | #define my_sha_result ymy_sha_result(NUM) |
121 | #define my_sha ymy_sha(NUM) |
122 | |
123 | /** |
124 | Wrapper function to compute SHAn message digest. |
125 | |
126 | @param digest [out] Computed SHAn digest |
127 | @param buf [in] Message to be computed |
128 | @param len [in] Length of the message |
129 | |
130 | @return void |
131 | */ |
132 | void my_sha(uchar *digest, const char *buf, size_t len) |
133 | { |
134 | CONTEXT context; |
135 | |
136 | sha_init_fast(&context); |
137 | sha_input(&context, (const uchar *)buf, (unsigned int)len); |
138 | sha_result(&context, digest); |
139 | } |
140 | |
141 | |
142 | /** |
143 | Wrapper function to compute SHAn message digest for |
144 | two messages in order to emulate shaN(msg1, msg2). |
145 | |
146 | @param digest [out] Computed SHAn digest |
147 | @param buf1 [in] First message |
148 | @param len1 [in] Length of first message |
149 | @param buf2 [in] Second message |
150 | @param len2 [in] Length of second message |
151 | |
152 | @return void |
153 | */ |
154 | void my_sha_multi(uchar *digest, ...) |
155 | { |
156 | va_list args; |
157 | va_start(args, digest); |
158 | |
159 | CONTEXT context; |
160 | const uchar *str; |
161 | |
162 | sha_init_fast(&context); |
163 | for (str= va_arg(args, const uchar*); str; str= va_arg(args, const uchar*)) |
164 | sha_input(&context, str, (uint) va_arg(args, size_t)); |
165 | |
166 | sha_result(&context, digest); |
167 | va_end(args); |
168 | } |
169 | |
170 | size_t my_sha_context_size() |
171 | { |
172 | return sizeof(CONTEXT); |
173 | } |
174 | |
175 | void my_sha_init(void *context) |
176 | { |
177 | sha_init((CONTEXT *)context); |
178 | } |
179 | |
180 | void my_sha_input(void *context, const uchar *buf, size_t len) |
181 | { |
182 | sha_input((CONTEXT *)context, buf, (uint) len); |
183 | } |
184 | |
185 | void my_sha_result(void *context, uchar *digest) |
186 | { |
187 | sha_result((CONTEXT *)context, digest); |
188 | } |
189 | |