EVP_MAC: Add SipHash implementation

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/7494)
This commit is contained in:
Richard Levitte 2018-10-25 00:17:45 +02:00
parent cf3d6ef7af
commit c89d9cdab1
8 changed files with 211 additions and 4 deletions

View file

@ -16,4 +16,7 @@ void openssl_add_all_macs_int(void)
EVP_add_mac(&cmac_meth);
#endif
EVP_add_mac(&hmac_meth);
#ifndef OPENSSL_NO_SIPHASH
EVP_add_mac(&siphash_meth);
#endif
}

View file

@ -130,6 +130,7 @@ struct evp_mac_st {
extern const EVP_MAC cmac_meth;
extern const EVP_MAC hmac_meth;
extern const EVP_MAC siphash_meth;
/*
* This function is internal for now, but can be made external when needed.

View file

@ -1,5 +1,6 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]=\
siphash.c \
siphash_meth.c \
siphash_pmeth.c \
siphash_ameth.c

View file

@ -0,0 +1,139 @@
/*
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <stdarg.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include "internal/siphash.h"
#include "siphash_local.h"
#include "internal/evp_int.h"
/* local SIPHASH structure is actually a SIPHASH */
struct evp_mac_impl_st {
SIPHASH ctx;
};
static EVP_MAC_IMPL *siphash_new(void)
{
return OPENSSL_zalloc(sizeof(EVP_MAC_IMPL));
}
static void siphash_free(EVP_MAC_IMPL *sctx)
{
OPENSSL_free(sctx);
}
static int siphash_copy(EVP_MAC_IMPL *sdst, EVP_MAC_IMPL *ssrc)
{
*sdst = *ssrc;
return 1;
}
static size_t siphash_size(EVP_MAC_IMPL *sctx)
{
return SipHash_hash_size(&sctx->ctx);
}
static int siphash_init(EVP_MAC_IMPL *sctx)
{
/* Not much to do here, actual initialization happens through controls */
return 1;
}
static int siphash_update(EVP_MAC_IMPL *sctx, const unsigned char *data,
size_t datalen)
{
SipHash_Update(&sctx->ctx, data, datalen);
return 1;
}
static int siphash_final(EVP_MAC_IMPL *sctx, unsigned char *out)
{
size_t hlen = siphash_size(sctx);
return SipHash_Final(&sctx->ctx, out, hlen);
}
static int siphash_ctrl(EVP_MAC_IMPL *sctx, int cmd, va_list args)
{
switch (cmd) {
case EVP_MAC_CTRL_SET_SIZE:
{
size_t size = va_arg(args, size_t);
return SipHash_set_hash_size(&sctx->ctx, size);
}
break;
case EVP_MAC_CTRL_SET_KEY:
{
const unsigned char *key = va_arg(args, const unsigned char *);
size_t keylen = va_arg(args, size_t);
if (key == NULL || keylen != SIPHASH_KEY_SIZE)
return 0;
return SipHash_Init(&sctx->ctx, key, 0, 0);
}
break;
default:
return -2;
}
return 1;
}
static int siphash_ctrl_int(EVP_MAC_IMPL *sctx, int cmd, ...)
{
int rv;
va_list args;
va_start(args, cmd);
rv = siphash_ctrl(sctx, cmd, args);
va_end(args);
return rv;
}
static int siphash_ctrl_str_cb(void *ctx, int cmd, void *buf, size_t buflen)
{
return siphash_ctrl_int(ctx, cmd, buf, buflen);
}
static int siphash_ctrl_str(EVP_MAC_IMPL *ctx,
const char *type, const char *value)
{
if (value == NULL)
return 0;
if (strcmp(type, "digestsize") == 0) {
size_t hash_size = atoi(value);
return siphash_ctrl_int(ctx, EVP_MAC_CTRL_SET_SIZE, hash_size);
}
if (strcmp(type, "key") == 0)
return EVP_str2ctrl(siphash_ctrl_str_cb, ctx, EVP_MAC_CTRL_SET_KEY,
value);
if (strcmp(type, "hexkey") == 0)
return EVP_hex2ctrl(siphash_ctrl_str_cb, ctx, EVP_MAC_CTRL_SET_KEY,
value);
return -2;
}
const EVP_MAC siphash_meth = {
EVP_MAC_SIPHASH,
siphash_new,
siphash_copy,
siphash_free,
siphash_size,
siphash_init,
siphash_update,
siphash_final,
siphash_ctrl,
siphash_ctrl_str
};

View file

@ -327,7 +327,8 @@ F<./foo>)
=head1 SEE ALSO
L<EVP_MAC_CMAC(7)>,
L<EVP_MAC_HMAC(7)>
L<EVP_MAC_HMAC(7)>,
L<EVP_MAC_SIPHASH(7)>
=head1 COPYRIGHT

View file

@ -0,0 +1,61 @@
=pod
=head1 NAME
EVP_MAC_SIPHASH - The SipHash EVP_MAC implementation
=head1 DESCRIPTION
Support for computing SipHash MACs through the B<EVP_MAC> API.
=head2 Numeric identity
B<EVP_MAC_SIPHASH> is the numeric identity for this implementation,
and can be used in functions like EVP_MAC_CTX_new_id() and
EVP_get_macbynid().
=head2 Supported controls
The supported controls are:
=over 4
=item B<EVP_MAC_CTRL_SET_SIZE>
EVP_MAC_ctrl_str() type string: "digestsize"
The value string is expected to contain a decimal number.
=item B<EVP_MAC_CTRL_SET_KEY>
EVP_MAC_ctrl_str() takes to type string for this control:
=over 4
=item "key"
The value string is used as is.
=item "hexkey"
The value string is expected to be a hexadecimal number, which will be
decoded before passing on as control value.
=back
=back
=head1 SEE ALSO
L<EVP_MAC_ctrl(3)>, L<EVP_MAC(3)/CONTROLS>
=head1 COPYRIGHT
Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the OpenSSL license (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View file

@ -987,8 +987,9 @@ void EVP_MD_do_all_sorted(void (*fn)
/* MAC stuff */
# define EVP_MAC_CMAC NID_cmac
# define EVP_MAC_HMAC NID_hmac
# define EVP_MAC_CMAC NID_cmac
# define EVP_MAC_HMAC NID_hmac
# define EVP_MAC_SIPHASH NID_siphash
EVP_MAC_CTX *EVP_MAC_CTX_new(const EVP_MAC *mac);
EVP_MAC_CTX *EVP_MAC_CTX_new_id(int nid);

View file

@ -157,7 +157,7 @@ Output = 5150d1772f50834a503e069a973fbd7c
MAC = SipHash
Ctrl = digestsize:13
Key = 000102030405060708090A0B0C0D0E0F
Result = EVPPKEYCTXCTRL_ERROR
Result = MAC_CTRL_ERROR
Title = HMAC tests (from RFC2104 and others)