summaryrefslogtreecommitdiff
path: root/mysys_ssl/my_sha.ic
blob: 97344dc04158561b6219cca29a4ea2bb219d231f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/* Copyright (c) 2012, Oracle and/or its affiliates.
   Copyright (c) 2014, 2017, MariaDB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */


/**
  @file

  @brief
  Wrapper functions for OpenSSL, YaSSL implementations. Also provides a
  Compatibility layer to make available YaSSL's SHAn implementation.
*/

#include <my_global.h>
#include <stdarg.h>

#define HASH_SIZE (NUM > 1 ? NUM/8 : 20)

#if defined(HAVE_YASSL)
#include "sha.hpp"

#define xCONTEXT(x)     TaoCrypt::SHA ## x
#define yCONTEXT(y)     xCONTEXT(y)
#define CONTEXT         yCONTEXT(NUM)
#define SHA1            SHA

static void sha_init(CONTEXT *context)
{
  context->Init();
}

/*
  this is a variant of sha_init to be used in this file only.
  does nothing for yassl, because the context's constructor was called automatically.
*/
static void sha_init_fast(CONTEXT *context)
{
}

static void sha_input(CONTEXT *context, const uchar *buf, unsigned len)
{
  context->Update((const TaoCrypt::byte *) buf, len);
}

static void sha_result(CONTEXT *context, uchar digest[HASH_SIZE])
{
    context->Final((TaoCrypt::byte *) digest);
}

#elif defined(HAVE_OPENSSL)
#include <openssl/sha.h>

#define xCONTEXT(x)     SHA ## x ## _CTX
#define yCONTEXT(y)     xCONTEXT(y)
#define CONTEXT         yCONTEXT(NUM)
#define SHA1_CTX        SHA_CTX
#define SHA224_CTX      SHA256_CTX
#define SHA384_CTX      SHA512_CTX

#define xSHA_Init(x)    SHA ## x ## _Init
#define xSHA_Update(x)  SHA ## x ## _Update
#define xSHA_Final(x)   SHA ## x ## _Final
#define ySHA_Init(y)    xSHA_Init(y)
#define ySHA_Update(y)  xSHA_Update(y)
#define ySHA_Final(y)   xSHA_Final(y)
#define SHA_Init        ySHA_Init(NUM)
#define SHA_Update      ySHA_Update(NUM)
#define SHA_Final       ySHA_Final(NUM)

static void sha_init(CONTEXT *context)
{
  SHA_Init(context);
}

static void sha_init_fast(CONTEXT *context)
{
  sha_init(context);
}

static void sha_input(CONTEXT *context, const uchar *buf, unsigned len)
{
  SHA_Update(context, buf, len);
}

static void sha_result(CONTEXT *context, uchar digest[HASH_SIZE])
{
  SHA_Final(digest, context);
}

#endif /* HAVE_YASSL */

#define xmy_sha_multi(x)         my_sha ## x ## _multi
#define xmy_sha_context_size(x)  my_sha ## x ## _context_size
#define xmy_sha_init(x)          my_sha ## x ## _init
#define xmy_sha_input(x)         my_sha ## x ## _input
#define xmy_sha_result(x)        my_sha ## x ## _result
#define xmy_sha(x)               my_sha ## x
#define ymy_sha_multi(y)         xmy_sha_multi(y)
#define ymy_sha_context_size(y)  xmy_sha_context_size(y)
#define ymy_sha_init(y)          xmy_sha_init(y)
#define ymy_sha_input(y)         xmy_sha_input(y)
#define ymy_sha_result(y)        xmy_sha_result(y)
#define ymy_sha(y)               xmy_sha(y)
#define my_sha_multi             ymy_sha_multi(NUM)
#define my_sha_context_size      ymy_sha_context_size(NUM)
#define my_sha_init              ymy_sha_init(NUM)
#define my_sha_input             ymy_sha_input(NUM)
#define my_sha_result            ymy_sha_result(NUM)
#define my_sha                   ymy_sha(NUM)

/**
  Wrapper function to compute SHAn message digest.

  @param digest [out]  Computed SHAn digest
  @param buf    [in]   Message to be computed
  @param len    [in]   Length of the message

  @return              void
*/
void my_sha(uchar *digest, const char *buf, size_t len)
{
  CONTEXT context;

  sha_init_fast(&context);
  sha_input(&context, (const uchar *)buf, (unsigned int)len);
  sha_result(&context, digest);
}


/**
  Wrapper function to compute SHAn message digest for
  two messages in order to emulate shaN(msg1, msg2).

  @param digest [out]  Computed SHAn digest
  @param buf1   [in]   First message
  @param len1   [in]   Length of first message
  @param buf2   [in]   Second message
  @param len2   [in]   Length of second message

  @return              void
*/
void my_sha_multi(uchar *digest, ...)
{
  va_list args;
  va_start(args, digest);

  CONTEXT context;
  const uchar *str;

  sha_init_fast(&context);
  for (str= va_arg(args, const uchar*); str; str= va_arg(args, const uchar*))
    sha_input(&context, str, (uint) va_arg(args, size_t));

  sha_result(&context, digest);
  va_end(args);
}

size_t my_sha_context_size()
{
  return sizeof(CONTEXT);
}

void my_sha_init(void *context)
{
  sha_init((CONTEXT *)context);
}

void my_sha_input(void *context, const uchar *buf, size_t len)
{
  sha_input((CONTEXT *)context, buf, (uint) len);
}

void my_sha_result(void *context, uchar *digest)
{
  sha_result((CONTEXT *)context, digest);
}