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, Suite 500, 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
34typedef TaoCrypt::MD5 EVP_MD_CTX;
35
36static void md5_init(EVP_MD_CTX *context)
37{
38 context= new(context) EVP_MD_CTX;
39 context->Init();
40}
41
42static void md5_input(EVP_MD_CTX *context, const uchar *buf, unsigned len)
43{
44 context->Update((const TaoCrypt::byte *) buf, len);
45}
46
47static 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
56static 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
66static void md5_input(EVP_MD_CTX *context, const uchar *buf, unsigned len)
67{
68 EVP_DigestUpdate(context, buf, len);
69}
70
71static 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*/
88void 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*/
110void 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
126size_t my_md5_context_size()
127{
128 return EVP_MD_CTX_SIZE;
129}
130
131void my_md5_init(void *context)
132{
133 md5_init((EVP_MD_CTX *)context);
134}
135
136void my_md5_input(void *context, const uchar *buf, size_t len)
137{
138 md5_input((EVP_MD_CTX *)context, buf, (uint) len);
139}
140
141void my_md5_result(void *context, uchar *digest)
142{
143 md5_result((EVP_MD_CTX *)context, digest);
144}
145