diff options
author | Hugo Landau <hlandau@openssl.org> | 2022-03-02 07:38:15 +0000 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2022-03-14 10:28:24 +0100 |
commit | 864853988e80517a563d2423d4fb742323995433 (patch) | |
tree | f73d46b5427a4baa362461820ded4741d1bea82f /demos/mac | |
parent | e04c2c02e8e6b9ec71d93c26c14167ceb2165ce8 (diff) |
Add EVP demo for SIPHASH
Fixes #14121.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17793)
Diffstat (limited to 'demos/mac')
-rw-r--r-- | demos/mac/siphash.c | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/demos/mac/siphash.c b/demos/mac/siphash.c new file mode 100644 index 0000000000..4d36a9d486 --- /dev/null +++ b/demos/mac/siphash.c @@ -0,0 +1,129 @@ +/* + * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (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 <stdio.h> +#include <stdlib.h> +#include <openssl/core_names.h> +#include <openssl/evp.h> +#include <openssl/params.h> +#include <openssl/err.h> + +/* + * Taken from the test vector from the paper "SipHash: a fast short-input PRF". + * https://www.aumasson.jp/siphash/siphash.pdf + */ + +/* + * Hard coding the key into an application is very bad. + * It is done here solely for educational purposes. + */ +static unsigned char key[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f +}; + +static unsigned char data[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e +}; + +static const unsigned char expected_output[] = { + 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1 +}; + +/* + * A property query used for selecting the SIPHASH implementation. + */ +static char *propq = NULL; + +int main(int argc, char **argv) +{ + int rv = EXIT_FAILURE; + EVP_MAC *mac = NULL; + EVP_MAC_CTX *mctx = NULL; + unsigned char out[8]; + OSSL_PARAM params[4], *p = params; + OSSL_LIB_CTX *library_context = NULL; + unsigned int digest_len = 8, c_rounds = 2, d_rounds = 4; + size_t out_len = 0; + + library_context = OSSL_LIB_CTX_new(); + if (library_context == NULL) { + fprintf(stderr, "OSSL_LIB_CTX_new() returned NULL\n"); + goto end; + } + + /* Fetch the SipHash implementation */ + mac = EVP_MAC_fetch(library_context, "SIPHASH", propq); + if (mac == NULL) { + fprintf(stderr, "EVP_MAC_fetch() returned NULL\n"); + goto end; + } + + /* Create a context for the SipHash operation */ + mctx = EVP_MAC_CTX_new(mac); + if (mctx == NULL) { + fprintf(stderr, "EVP_MAC_CTX_new() returned NULL\n"); + goto end; + } + + /* SipHash can support either 8 or 16-byte digests. */ + *p++ = OSSL_PARAM_construct_uint(OSSL_MAC_PARAM_SIZE, &digest_len); + + /* + * The number of C-rounds and D-rounds is configurable. Standard SipHash + * uses values of 2 and 4 respectively. The following lines are unnecessary + * as they set the default, but demonstrate how to change these values. + */ + *p++ = OSSL_PARAM_construct_uint(OSSL_MAC_PARAM_C_ROUNDS, &c_rounds); + *p++ = OSSL_PARAM_construct_uint(OSSL_MAC_PARAM_D_ROUNDS, &d_rounds); + + *p = OSSL_PARAM_construct_end(); + + /* Initialise the SIPHASH operation */ + if (!EVP_MAC_init(mctx, key, sizeof(key), params)) { + fprintf(stderr, "EVP_MAC_init() failed\n"); + goto end; + } + + /* Make one or more calls to process the data to be authenticated */ + if (!EVP_MAC_update(mctx, data, sizeof(data))) { + fprintf(stderr, "EVP_MAC_update() failed\n"); + goto end; + } + + /* Make one call to the final to get the MAC */ + if (!EVP_MAC_final(mctx, out, &out_len, sizeof(out))) { + fprintf(stderr, "EVP_MAC_final() failed\n"); + goto end; + } + + printf("Generated MAC:\n"); + BIO_dump_indent_fp(stdout, out, out_len, 2); + putchar('\n'); + + if (out_len != sizeof(expected_output)) { + fprintf(stderr, "Generated MAC has an unexpected length\n"); + goto end; + } + + if (CRYPTO_memcmp(expected_output, out, sizeof(expected_output)) != 0) { + fprintf(stderr, "Generated MAC does not match expected value\n"); + goto end; + } + + rv = EXIT_SUCCESS; +end: + EVP_MAC_CTX_free(mctx); + EVP_MAC_free(mac); + OSSL_LIB_CTX_free(library_context); + if (rv != EXIT_SUCCESS) + ERR_print_errors_fp(stderr); + return rv; +} |