libhashkit/aes: make using openssl configurable
[awesomized/libmemcached] / src / libhashkit / hashkit.cc
1 /*
2 +--------------------------------------------------------------------+
3 | libmemcached-awesome - C/C++ Client Library for memcached |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted under the terms of the BSD license. |
7 | You should have received a copy of the license in a bundled file |
8 | named LICENSE; in case you did not receive a copy you can review |
9 | the terms online at: https://opensource.org/licenses/BSD-3-Clause |
10 +--------------------------------------------------------------------+
11 | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
12 | Copyright (c) 2020-2021 Michael Wallner https://awesome.co/ |
13 +--------------------------------------------------------------------+
14 */
15
16 #include "libhashkit/common.h"
17
18 #ifdef HAVE_OPENSSL_CRYPTO
19 # include <openssl/evp.h>
20 #endif
21
22 static inline void _hashkit_init(hashkit_st *self) {
23 self->base_hash.function = hashkit_one_at_a_time;
24 self->base_hash.context = NULL;
25
26 self->distribution_hash.function = hashkit_one_at_a_time;
27 self->distribution_hash.context = NULL;
28
29 self->flags.is_base_same_distributed = true;
30 self->_cryptographic_context = NULL;
31 }
32
33 static inline hashkit_st *_hashkit_create(hashkit_st *self) {
34 if (self) {
35 self->options.is_allocated = false;
36 } else {
37 self = (hashkit_st *) calloc(1, sizeof(hashkit_st));
38 if (self == NULL) {
39 return NULL;
40 }
41
42 self->options.is_allocated = true;
43 }
44
45 return self;
46 }
47
48 hashkit_st *hashkit_create(hashkit_st *self) {
49 self = _hashkit_create(self);
50 if (self == NULL) {
51 return NULL;
52 }
53
54 _hashkit_init(self);
55
56 return self;
57 }
58
59 #ifdef HAVE_OPENSSL_CRYPTO
60 static void cryptographic_context_free(encryption_context_t *context) {
61 EVP_CIPHER_CTX_free(context->encryption_context);
62 EVP_CIPHER_CTX_free(context->decryption_context);
63 free(context);
64 }
65 #endif
66
67 void hashkit_free(hashkit_st *self) {
68 #ifdef HAVE_OPENSSL_CRYPTO
69 if (self and self->_cryptographic_context) {
70 cryptographic_context_free((encryption_context_t *)self->_cryptographic_context);
71 self->_cryptographic_context = NULL;
72 }
73 #else
74 if (self and self->_cryptographic_context) {
75 free(self->_cryptographic_context);
76 self->_cryptographic_context = NULL;
77 }
78 #endif
79
80 if (hashkit_is_allocated(self)) {
81 free(self);
82 }
83 }
84
85 hashkit_st *hashkit_clone(hashkit_st *destination, const hashkit_st *source) {
86 if (source == NULL) {
87 return hashkit_create(destination);
88 }
89
90 /* new_clone will be a pointer to destination */
91 destination = _hashkit_create(destination);
92
93 // Should only happen on allocation failure.
94 if (destination == NULL) {
95 return NULL;
96 }
97
98 destination->base_hash = source->base_hash;
99 destination->distribution_hash = source->distribution_hash;
100 destination->flags = source->flags;
101 #ifdef HAVE_OPENSSL_CRYPTO
102 if (destination->_cryptographic_context) {
103 cryptographic_context_free((encryption_context_t *)destination->_cryptographic_context);
104 destination->_cryptographic_context = NULL;
105 }
106 if (source->_cryptographic_context) {
107 destination->_cryptographic_context =
108 aes_clone_cryptographic_context(((encryption_context_t *) source->_cryptographic_context));
109 if (destination->_cryptographic_context) {
110
111 }
112 }
113 #else
114 destination->_cryptographic_context = aes_clone_key(static_cast<aes_key_t *>(source->_cryptographic_context));
115 #endif
116
117 return destination;
118 }
119
120 bool hashkit_compare(const hashkit_st *first, const hashkit_st *second) {
121 if (not first or not second)
122 return false;
123
124 if (first->base_hash.function == second->base_hash.function
125 and first->base_hash.context == second->base_hash.context
126 and first->distribution_hash.function == second->distribution_hash.function
127 and first->distribution_hash.context == second->distribution_hash.context
128 and first->flags.is_base_same_distributed == second->flags.is_base_same_distributed)
129 {
130 return true;
131 }
132
133 return false;
134 }