]>
Commit | Line | Data |
---|---|---|
86485398 | 1 | /* |
da1c088f | 2 | * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. |
86485398 HL |
3 | * |
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use | |
5 | * this file except in compliance with the License. You can obtain a copy | |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
8 | */ | |
9 | ||
10 | #include <stdio.h> | |
11 | #include <stdlib.h> | |
12 | #include <openssl/core_names.h> | |
13 | #include <openssl/evp.h> | |
14 | #include <openssl/params.h> | |
15 | #include <openssl/err.h> | |
16 | ||
17 | /* | |
18 | * Taken from the test vector from the paper "SipHash: a fast short-input PRF". | |
19 | * https://www.aumasson.jp/siphash/siphash.pdf | |
20 | */ | |
21 | ||
22 | /* | |
23 | * Hard coding the key into an application is very bad. | |
24 | * It is done here solely for educational purposes. | |
25 | */ | |
26 | static unsigned char key[] = { | |
27 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | |
28 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f | |
29 | }; | |
30 | ||
31 | static unsigned char data[] = { | |
32 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | |
33 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e | |
34 | }; | |
35 | ||
36 | static const unsigned char expected_output[] = { | |
37 | 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1 | |
38 | }; | |
39 | ||
40 | /* | |
41 | * A property query used for selecting the SIPHASH implementation. | |
42 | */ | |
43 | static char *propq = NULL; | |
44 | ||
45 | int main(int argc, char **argv) | |
46 | { | |
09ff84bd | 47 | int ret = EXIT_FAILURE; |
86485398 HL |
48 | EVP_MAC *mac = NULL; |
49 | EVP_MAC_CTX *mctx = NULL; | |
50 | unsigned char out[8]; | |
51 | OSSL_PARAM params[4], *p = params; | |
52 | OSSL_LIB_CTX *library_context = NULL; | |
53 | unsigned int digest_len = 8, c_rounds = 2, d_rounds = 4; | |
54 | size_t out_len = 0; | |
55 | ||
56 | library_context = OSSL_LIB_CTX_new(); | |
57 | if (library_context == NULL) { | |
58 | fprintf(stderr, "OSSL_LIB_CTX_new() returned NULL\n"); | |
59 | goto end; | |
60 | } | |
61 | ||
62 | /* Fetch the SipHash implementation */ | |
63 | mac = EVP_MAC_fetch(library_context, "SIPHASH", propq); | |
64 | if (mac == NULL) { | |
65 | fprintf(stderr, "EVP_MAC_fetch() returned NULL\n"); | |
66 | goto end; | |
67 | } | |
68 | ||
69 | /* Create a context for the SipHash operation */ | |
70 | mctx = EVP_MAC_CTX_new(mac); | |
71 | if (mctx == NULL) { | |
72 | fprintf(stderr, "EVP_MAC_CTX_new() returned NULL\n"); | |
73 | goto end; | |
74 | } | |
75 | ||
76 | /* SipHash can support either 8 or 16-byte digests. */ | |
77 | *p++ = OSSL_PARAM_construct_uint(OSSL_MAC_PARAM_SIZE, &digest_len); | |
78 | ||
79 | /* | |
80 | * The number of C-rounds and D-rounds is configurable. Standard SipHash | |
81 | * uses values of 2 and 4 respectively. The following lines are unnecessary | |
82 | * as they set the default, but demonstrate how to change these values. | |
83 | */ | |
84 | *p++ = OSSL_PARAM_construct_uint(OSSL_MAC_PARAM_C_ROUNDS, &c_rounds); | |
85 | *p++ = OSSL_PARAM_construct_uint(OSSL_MAC_PARAM_D_ROUNDS, &d_rounds); | |
86 | ||
87 | *p = OSSL_PARAM_construct_end(); | |
88 | ||
89 | /* Initialise the SIPHASH operation */ | |
90 | if (!EVP_MAC_init(mctx, key, sizeof(key), params)) { | |
91 | fprintf(stderr, "EVP_MAC_init() failed\n"); | |
92 | goto end; | |
93 | } | |
94 | ||
95 | /* Make one or more calls to process the data to be authenticated */ | |
96 | if (!EVP_MAC_update(mctx, data, sizeof(data))) { | |
97 | fprintf(stderr, "EVP_MAC_update() failed\n"); | |
98 | goto end; | |
99 | } | |
100 | ||
101 | /* Make one call to the final to get the MAC */ | |
102 | if (!EVP_MAC_final(mctx, out, &out_len, sizeof(out))) { | |
103 | fprintf(stderr, "EVP_MAC_final() failed\n"); | |
104 | goto end; | |
105 | } | |
106 | ||
107 | printf("Generated MAC:\n"); | |
108 | BIO_dump_indent_fp(stdout, out, out_len, 2); | |
109 | putchar('\n'); | |
110 | ||
111 | if (out_len != sizeof(expected_output)) { | |
112 | fprintf(stderr, "Generated MAC has an unexpected length\n"); | |
113 | goto end; | |
114 | } | |
115 | ||
116 | if (CRYPTO_memcmp(expected_output, out, sizeof(expected_output)) != 0) { | |
117 | fprintf(stderr, "Generated MAC does not match expected value\n"); | |
118 | goto end; | |
119 | } | |
120 | ||
09ff84bd | 121 | ret = EXIT_SUCCESS; |
86485398 HL |
122 | end: |
123 | EVP_MAC_CTX_free(mctx); | |
124 | EVP_MAC_free(mac); | |
125 | OSSL_LIB_CTX_free(library_context); | |
09ff84bd | 126 | if (ret != EXIT_SUCCESS) |
86485398 | 127 | ERR_print_errors_fp(stderr); |
09ff84bd | 128 | return ret; |
86485398 | 129 | } |