1 /* Copyright (c) 2012, Oracle and/or its affiliates.
2    Copyright (c) 2017, MariaDB Corporation
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, Fifth Floor, Boston, MA 02110-1335 USA */
16 
17 
18 /**
19   @file
20 
21   @brief
22   Wrapper functions for OpenSSL and YaSSL. Also provides a Compatibility layer
23   to make available YaSSL's MD5 implementation.
24 */
25 
26 #include <my_global.h>
27 #include <my_md5.h>
28 #include <stdarg.h>
29 
30 #if defined(HAVE_YASSL)
31 #include "md5.hpp"
32 #include <ssl_compat.h>
33 
34 typedef TaoCrypt::MD5 EVP_MD_CTX;
35 
md5_init(EVP_MD_CTX * context)36 static void md5_init(EVP_MD_CTX *context)
37 {
38   context= new(context) EVP_MD_CTX;
39   context->Init();
40 }
41 
md5_input(EVP_MD_CTX * context,const uchar * buf,unsigned len)42 static void md5_input(EVP_MD_CTX *context, const uchar *buf, unsigned len)
43 {
44   context->Update((const TaoCrypt::byte *) buf, len);
45 }
46 
md5_result(EVP_MD_CTX * context,uchar digest[MD5_HASH_SIZE])47 static void md5_result(EVP_MD_CTX *context, uchar digest[MD5_HASH_SIZE])
48 {
49     context->Final((TaoCrypt::byte *) digest);
50 }
51 
52 #elif defined(HAVE_OPENSSL)
53 #include <openssl/evp.h>
54 #include <ssl_compat.h>
55 
md5_init(EVP_MD_CTX * context)56 static void md5_init(EVP_MD_CTX *context)
57 {
58   EVP_MD_CTX_init(context);
59 #ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
60   /* Ok to ignore FIPS: MD5 is not used for crypto here */
61   EVP_MD_CTX_set_flags(context, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
62 #endif
63   EVP_DigestInit_ex(context, EVP_md5(), NULL);
64 }
65 
md5_input(EVP_MD_CTX * context,const uchar * buf,unsigned len)66 static void md5_input(EVP_MD_CTX *context, const uchar *buf, unsigned len)
67 {
68   EVP_DigestUpdate(context, buf, len);
69 }
70 
md5_result(EVP_MD_CTX * context,uchar digest[MD5_HASH_SIZE])71 static void md5_result(EVP_MD_CTX *context, uchar digest[MD5_HASH_SIZE])
72 {
73   EVP_DigestFinal_ex(context, digest, NULL);
74   EVP_MD_CTX_reset(context);
75 }
76 
77 #endif /* HAVE_YASSL */
78 
79 /**
80   Wrapper function to compute MD5 message digest.
81 
82   @param digest [out]  Computed MD5 digest
83   @param buf    [in]   Message to be computed
84   @param len    [in]   Length of the message
85 
86   @return              void
87 */
my_md5(uchar * digest,const char * buf,size_t len)88 void my_md5(uchar *digest, const char *buf, size_t len)
89 {
90   char ctx_buf[EVP_MD_CTX_SIZE];
91   EVP_MD_CTX * const ctx= (EVP_MD_CTX*)ctx_buf;
92   md5_init(ctx);
93   md5_input(ctx, (const uchar *)buf, (uint) len);
94   md5_result(ctx, digest);
95 }
96 
97 
98 /**
99   Wrapper function to compute MD5 message digest for
100   many messages, concatenated.
101 
102   @param digest [out]  Computed MD5 digest
103   @param buf1   [in]   First message
104   @param len1   [in]   Length of first message
105          ...
106   @param bufN   [in]   NULL terminates the list of buf,len pairs.
107 
108   @return              void
109 */
my_md5_multi(uchar * digest,...)110 void my_md5_multi(uchar *digest, ...)
111 {
112   va_list args;
113   const uchar *str;
114   char ctx_buf[EVP_MD_CTX_SIZE];
115   EVP_MD_CTX * const ctx= (EVP_MD_CTX*)ctx_buf;
116   va_start(args, digest);
117 
118   md5_init(ctx);
119   for (str= va_arg(args, const uchar*); str; str= va_arg(args, const uchar*))
120     md5_input(ctx, str, (uint) va_arg(args, size_t));
121 
122   md5_result(ctx, digest);
123   va_end(args);
124 }
125 
my_md5_context_size()126 size_t my_md5_context_size()
127 {
128   return EVP_MD_CTX_SIZE;
129 }
130 
my_md5_init(void * context)131 void my_md5_init(void *context)
132 {
133   md5_init((EVP_MD_CTX *)context);
134 }
135 
my_md5_input(void * context,const uchar * buf,size_t len)136 void my_md5_input(void *context, const uchar *buf, size_t len)
137 {
138   md5_input((EVP_MD_CTX *)context, buf, (uint) len);
139 }
140 
my_md5_result(void * context,uchar * digest)141 void my_md5_result(void *context, uchar *digest)
142 {
143   md5_result((EVP_MD_CTX *)context, digest);
144 }
145