Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
CONC-312:
Added caching_sha2_plugin:
Fully supported with OpenSSL and Schannel. Partially supported with GnuTLS (only if using a secure connection)
  • Loading branch information
9EOR9 committed Feb 24, 2018
1 parent 336266c commit aeb4111
Show file tree
Hide file tree
Showing 6 changed files with 988 additions and 113 deletions.
186 changes: 186 additions & 0 deletions include/ma_crypt.h
@@ -0,0 +1,186 @@
/*
Copyright (C) 2018 MariaDB Corporation AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not see <http://www.gnu.org/licenses>
or write to the Free Software Foundation, Inc.,
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
*/

#ifndef _ma_hash_h_
#define _ma_hash_h_

#include <stddef.h>
#include <stdarg.h>

/*! Hash algorithms */
#define MA_HASH_MD5 1
#define MA_HASH_SHA1 2
#define MA_HASH_SHA224 3
#define MA_HASH_SHA256 4
#define MA_HASH_SHA384 5
#define MA_HASH_SHA512 6
#define MA_HASH_RIPEMD160 7

/*! Hash digest sizes */
#define MA_MD5_HASH_SIZE 16
#define MA_SHA1_HASH_SIZE 20
#define MA_SHA224_HASH_SIZE 28
#define MA_SHA256_HASH_SIZE 32
#define MA_SHA384_HASH_SIZE 48
#define MA_SHA512_HASH_SIZE 64
#define MA_RIPEMD160_HASH_SIZE 20

#define MA_MAX_HASH_SIZE 64
/** \typedef MRL hash context */

#if defined(HAVE_OPENSSL)
typedef void MA_HASH_CTX;
#elif defined(HAVE_GNUTLS)
typedef struct {
void *ctx;
const struct nettle_hash *hash;
} MA_HASH_CTX;
#elif defined(HAVE_SCHANNEL)
typedef struct {
BCRYPT_ALG_HANDLE hAlg;
BCRYPT_HASH_HANDLE hHash;
PBYTE hashObject;
char digest[MA_MAX_HASH_SIZE];
DWORD digest_len;
} MA_HASH_CTX;
#endif

/**
@brief acquire and initialize new hash context
@param[in] algorithm hash algorithm
@return hash context on success, NULL on error
*/
MA_HASH_CTX *ma_hash_new(unsigned int algorithm);

/**
@brief release and deinitializes a hash context
@param[in] hash context
@return void
*/
void ma_hash_free(MA_HASH_CTX *ctx);

/**
@brief hashes len bytes of data into the hash context.
This function can be called several times on same context to
hash additional data.
@param[in] ctx hash context
@param[in] buffer data buffer
@param[in] len size of buffer
@return void
*/
void ma_hash_input(MA_HASH_CTX *ctx,
const unsigned char *buffer,
size_t len);

/**
@brief retrieves the hash value from hash context
@param[in] ctx hash context
@param[out] digest digest containing hash value
@return void
*/
void ma_hash_result(MA_HASH_CTX *ctx, unsigned char *digest);

/**
@brief wrapper function to compute hash from one or more
buffers.
@param[in] hash_alg ] hash algorithm
@param[out] digest] computed hash digest
@param[in] ... variable argument list containg touples of
message and message lengths. Last parameter
must be always NULL.
@return void
*/
void ma_hash_va(unsigned int hash_alg,
unsigned char *digest,
va_list args);

/**
@brief wrapper function to compute hash from one or more
buffers.
@param[in] hash_alg ] hashing hash_alg
@param[out] digest] computed hash digest
@param[in] ... variable arguments containg touples of
message and message lengths. Last parameter
must be always NULL.
@return void
*/
void ma_hash_v(unsigned int hash_alg,
unsigned char *digest,
...);

/**
@brief wrapper function to compute hash from message buffer
@param[in] hash_alg hash algorithm
@param[out] digest computed hash digest
@param[in] buffer message buffer
@param[in] length length of message buffer
@return void
*/
static inline void ma_hash(unsigned int hash_alg,
unsigned char *digest,
const unsigned char *buffer,
size_t length)
{
ma_hash_v(hash_alg, digest, buffer, length, NULL, 0);
}

/**
@brief returns digest size for a given hash algorithm
@param[in] hash algorithm
@retuns digest size or 0 on error
*/
static inline size_t ma_hash_digest_size(unsigned int hash_alg)
{
switch(hash_alg) {
case MA_HASH_MD5:
return MA_MD5_HASH_SIZE;
case MA_HASH_SHA1:
return MA_SHA1_HASH_SIZE;
case MA_HASH_SHA224:
return MA_SHA224_HASH_SIZE;
case MA_HASH_SHA256:
return MA_SHA256_HASH_SIZE;
case MA_HASH_SHA384:
return MA_SHA384_HASH_SIZE;
case MA_HASH_SHA512:
return MA_SHA512_HASH_SIZE;
case MA_HASH_RIPEMD160:
return MA_RIPEMD160_HASH_SIZE;
default:
return 0;
}
}

#endif /* _ma_hash_h_ */
75 changes: 75 additions & 0 deletions libmariadb/secure/gnutls_crypt.c
@@ -0,0 +1,75 @@
/*
Copyright (C) 2018 MariaDB Corporation AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not see <http://www.gnu.org/licenses>
or write to the Free Software Foundation, Inc.,
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
*/
#include <ma_crypt.h>
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>

static gnutls_digest_algorithm_t ma_hash_get_algorithm(unsigned int alg)
{
switch(alg)
{
case MA_HASH_MD5:
return GNUTLS_DIG_MD5;
case MA_HASH_SHA1:
return GNUTLS_DIG_SHA1;
case MA_HASH_SHA256:
return GNUTLS_DIG_SHA256;
case MA_HASH_SHA384:
return GNUTLS_DIG_SHA384;
case MA_HASH_SHA512:
return GNUTLS_DIG_SHA512;
case MA_HASH_RIPEMD160:
return GNUTLS_DIG_RMD160;
default:
return GNUTLS_DIG_UNKNOWN;
}
}

MA_HASH_CTX *ma_hash_new(unsigned int algorithm)
{
gnutls_hash_hd_t ctx= NULL;
gnutls_digest_algorithm_t hash_alg= ma_hash_get_algorithm(algorithm);

/* unknown or unsupported hash algorithm */
if (hash_alg == GNUTLS_DIG_UNKNOWN)
return NULL;

if (gnutls_hash_init(&ctx, hash_alg) < 0)
return NULL;

return (MA_HASH_CTX *)ctx;
}

void ma_hash_free(MA_HASH_CTX *ctx)
{
if (ctx)
gnutls_hash_deinit((gnutls_hash_hd_t)ctx, NULL);
}

void ma_hash_input(MA_HASH_CTX *ctx,
const unsigned char *buffer,
size_t len)
{
gnutls_hash((gnutls_hash_hd_t)ctx, (const void *)buffer, len);
}

void ma_hash_result(MA_HASH_CTX *ctx, unsigned char *digest)
{
gnutls_hash_output((gnutls_hash_hd_t)ctx, digest);
}
87 changes: 87 additions & 0 deletions libmariadb/secure/openssl_crypt.c
@@ -0,0 +1,87 @@
/*
Copyright (C) 2018 MariaDB Corporation AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not see <http://www.gnu.org/licenses>
or write to the Free Software Foundation, Inc.,
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
*/
#include <ma_crypt.h>
#include <openssl/evp.h>

static const EVP_MD *ma_hash_get_algorithm(unsigned int alg)
{
switch(alg)
{
case MA_HASH_MD5:
return EVP_md5();
case MA_HASH_SHA1:
return EVP_sha1();
case MA_HASH_SHA224:
return EVP_sha224();
case MA_HASH_SHA256:
return EVP_sha256();
case MA_HASH_SHA384:
return EVP_sha384();
case MA_HASH_SHA512:
return EVP_sha512();
case MA_HASH_RIPEMD160:
return EVP_ripemd160();
default:
return NULL;
}
}

MA_HASH_CTX *ma_hash_new(unsigned int algorithm)
{
EVP_MD_CTX *ctx= NULL;
const EVP_MD *evp_md= ma_hash_get_algorithm(algorithm);

/* unknown or unsupported hash algorithm */
if (!evp_md)
return NULL;
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
if (!(ctx= EVP_MD_CTX_new()))
#else
if (!(ctx= EVP_MD_CTX_create()))
#endif
return NULL;
if (!EVP_DigestInit(ctx, evp_md))
{
ma_hash_free(ctx);
return NULL;
}
return ctx;
}

void ma_hash_free(MA_HASH_CTX *ctx)
{
if (ctx)
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
EVP_MD_CTX_free(ctx);
#else
EVP_MD_CTX_destroy(ctx);
#endif
}

void ma_hash_input(MA_HASH_CTX *ctx,
const unsigned char *buffer,
size_t len)
{
EVP_DigestUpdate(ctx, buffer, len);
}

void ma_hash_result(MA_HASH_CTX *ctx, unsigned char *digest)
{
EVP_DigestFinal_ex(ctx, digest, NULL);
}

0 comments on commit aeb4111

Please sign in to comment.