AWS Encryption SDK for C v2.4
Loading...
Searching...
No Matches
cache.h
Go to the documentation of this file.
1/*
2 * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. A copy of the License is
6 * located at
7 *
8 * http://aws.amazon.com/apache2.0/
9 *
10 * or in the "license" file accompanying this file. This file is distributed on an
11 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 * implied. See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef AWS_CRYPTOSDK_CACHE_H
17#define AWS_CRYPTOSDK_CACHE_H
18
19#include <aws/common/clock.h>
20
21#include <aws/cryptosdk/exports.h>
23#include <aws/cryptosdk/vtable.h>
24
25AWS_EXTERN_C_BEGIN
26
57
58#define AWS_CRYPTOSDK_CACHE_MAX_LIMIT_MESSAGES ((uint64_t)1 << 32)
59
63#ifdef AWS_CRYPTOSDK_DOXYGEN
64struct aws_cryptosdk_materials_cache;
65#else
66struct aws_cryptosdk_materials_cache {
67 struct aws_atomic_var refcount;
68 const struct aws_cryptosdk_materials_cache_vt *vt;
69};
70#endif
71
72#ifndef AWS_CRYPTOSDK_DOXYGEN
77
86struct aws_cryptosdk_materials_cache_entry;
87
88struct aws_cryptosdk_cache_usage_stats {
89 uint64_t bytes_encrypted, messages_encrypted;
90};
91
92AWS_CRYPTOSDK_STATIC_INLINE
93void aws_cryptosdk_materials_cache_base_init(
94 struct aws_cryptosdk_materials_cache *cache, const struct aws_cryptosdk_materials_cache_vt *vt) {
95 cache->vt = vt;
96 aws_atomic_init_int(&cache->refcount, 1);
97}
98
99struct aws_cryptosdk_materials_cache_vt {
103 size_t vt_size;
104
108 const char *name;
109
128
129 int (*find_entry)(
130 struct aws_cryptosdk_materials_cache *cache,
131 struct aws_cryptosdk_materials_cache_entry **entry,
132 bool *is_encrypt,
133 const struct aws_byte_buf *cache_id);
134
153 int (*update_usage_stats)(
154 struct aws_cryptosdk_materials_cache *cache,
155 struct aws_cryptosdk_materials_cache_entry *entry,
156 struct aws_cryptosdk_cache_usage_stats *usage_stats);
157
173 int (*get_enc_materials)(
174 struct aws_cryptosdk_materials_cache *cache,
175 struct aws_allocator *allocator,
176 struct aws_cryptosdk_enc_materials **materials,
177 struct aws_hash_table *enc_ctx,
178 struct aws_cryptosdk_materials_cache_entry *entry);
179
191 int (*get_dec_materials)(
192 const struct aws_cryptosdk_materials_cache *cache,
193 struct aws_allocator *allocator,
194 struct aws_cryptosdk_dec_materials **materials,
195 const struct aws_cryptosdk_materials_cache_entry *entry);
196
215 void (*put_entry_for_encrypt)(
216 struct aws_cryptosdk_materials_cache *cache,
217 struct aws_cryptosdk_materials_cache_entry **entry,
218 const struct aws_cryptosdk_enc_materials *enc_materials,
219 struct aws_cryptosdk_cache_usage_stats initial_usage,
220 const struct aws_hash_table *enc_ctx,
221 const struct aws_byte_buf *cache_id);
222
237 void (*put_entry_for_decrypt)(
238 struct aws_cryptosdk_materials_cache *cache,
239 struct aws_cryptosdk_materials_cache_entry **entry,
240 const struct aws_cryptosdk_dec_materials *dec_materials,
241 const struct aws_byte_buf *cache_id);
242
249 void (*destroy)(struct aws_cryptosdk_materials_cache *cache);
250
251 size_t (*entry_count)(const struct aws_cryptosdk_materials_cache *cache);
252
258 void (*entry_release)(
259 struct aws_cryptosdk_materials_cache *cache,
260 struct aws_cryptosdk_materials_cache_entry *entry,
261 bool invalidate);
262
267 uint64_t (*entry_get_creation_time)(
268 const struct aws_cryptosdk_materials_cache *cache, const struct aws_cryptosdk_materials_cache_entry *entry);
269
275 void (*entry_ttl_hint)(
276 struct aws_cryptosdk_materials_cache *cache,
277 struct aws_cryptosdk_materials_cache_entry *entry,
278 uint64_t exp_time);
279
285 void (*clear)(struct aws_cryptosdk_materials_cache *cache);
286};
287
288AWS_CRYPTOSDK_STATIC_INLINE
289int aws_cryptosdk_materials_cache_find_entry(
290 struct aws_cryptosdk_materials_cache *cache,
291 struct aws_cryptosdk_materials_cache_entry **entry,
292 bool *is_encrypt,
293 const struct aws_byte_buf *cache_id) {
294 int (*find_entry)(
295 struct aws_cryptosdk_materials_cache * cache,
296 struct aws_cryptosdk_materials_cache_entry * *entry,
297 bool *is_encrypt,
298 const struct aws_byte_buf *cache_id) = AWS_CRYPTOSDK_PRIVATE_VT_GET_NULL(cache->vt, find_entry);
299
300 *entry = NULL;
301 if (find_entry) {
302 return find_entry(cache, entry, is_encrypt, cache_id);
303 }
304
305 return AWS_OP_SUCCESS;
306}
307
308AWS_CRYPTOSDK_STATIC_INLINE
309int aws_cryptosdk_materials_cache_update_usage_stats(
310 struct aws_cryptosdk_materials_cache *cache,
311 struct aws_cryptosdk_materials_cache_entry *entry,
312 struct aws_cryptosdk_cache_usage_stats *usage_stats) {
313 int (*update_usage_stats)(
314 struct aws_cryptosdk_materials_cache * cache,
315 struct aws_cryptosdk_materials_cache_entry * entry,
316 struct aws_cryptosdk_cache_usage_stats * usage_stats) =
317 AWS_CRYPTOSDK_PRIVATE_VT_GET_NULL(cache->vt, update_usage_stats);
318
319 if (!update_usage_stats) {
320 return aws_raise_error(AWS_ERROR_UNSUPPORTED_OPERATION);
321 }
322
323 return update_usage_stats(cache, entry, usage_stats);
324}
325
326AWS_CRYPTOSDK_STATIC_INLINE
327int aws_cryptosdk_materials_cache_get_enc_materials(
328 struct aws_cryptosdk_materials_cache *cache,
329 struct aws_allocator *allocator,
330 struct aws_cryptosdk_enc_materials **materials,
331 struct aws_hash_table *enc_ctx,
332 struct aws_cryptosdk_materials_cache_entry *entry) {
333 int (*get_enc_materials)(
334 struct aws_cryptosdk_materials_cache * cache,
335 struct aws_allocator * allocator,
336 struct aws_cryptosdk_enc_materials * *materials,
337 struct aws_hash_table * enc_ctx,
338 struct aws_cryptosdk_materials_cache_entry * entry) =
339 AWS_CRYPTOSDK_PRIVATE_VT_GET_NULL(cache->vt, get_enc_materials);
340
341 *materials = NULL;
342 if (!get_enc_materials) {
343 return aws_raise_error(AWS_ERROR_UNSUPPORTED_OPERATION);
344 }
345
346 return get_enc_materials(cache, allocator, materials, enc_ctx, entry);
347}
348
349AWS_CRYPTOSDK_STATIC_INLINE
350int aws_cryptosdk_materials_cache_get_dec_materials(
351 const struct aws_cryptosdk_materials_cache *cache,
352 struct aws_allocator *allocator,
353 struct aws_cryptosdk_dec_materials **materials,
354 const struct aws_cryptosdk_materials_cache_entry *entry) {
355 int (*get_dec_materials)(
356 const struct aws_cryptosdk_materials_cache *cache,
357 struct aws_allocator *allocator,
358 struct aws_cryptosdk_dec_materials **materials,
359 const struct aws_cryptosdk_materials_cache_entry *entry) =
360 AWS_CRYPTOSDK_PRIVATE_VT_GET_NULL(cache->vt, get_dec_materials);
361
362 *materials = NULL;
363 if (!get_dec_materials) {
364 return aws_raise_error(AWS_ERROR_UNSUPPORTED_OPERATION);
365 }
366
367 return get_dec_materials(cache, allocator, materials, entry);
368}
369
370AWS_CRYPTOSDK_STATIC_INLINE
371void aws_cryptosdk_materials_cache_put_entry_for_encrypt(
372 struct aws_cryptosdk_materials_cache *cache,
373 struct aws_cryptosdk_materials_cache_entry **entry,
374 const struct aws_cryptosdk_enc_materials *enc_materials,
375 struct aws_cryptosdk_cache_usage_stats initial_usage,
376 const struct aws_hash_table *enc_ctx,
377 const struct aws_byte_buf *cache_id) {
378 void (*put_entry_for_encrypt)(
379 struct aws_cryptosdk_materials_cache * cache,
380 struct aws_cryptosdk_materials_cache_entry * *entry,
381 const struct aws_cryptosdk_enc_materials *enc_materials,
382 struct aws_cryptosdk_cache_usage_stats initial_usage,
383 const struct aws_hash_table *enc_ctx,
384 const struct aws_byte_buf *cache_id) = AWS_CRYPTOSDK_PRIVATE_VT_GET_NULL(cache->vt, put_entry_for_encrypt);
385
386 *entry = NULL;
387 if (put_entry_for_encrypt) {
388 put_entry_for_encrypt(cache, entry, enc_materials, initial_usage, enc_ctx, cache_id);
389 }
390}
391
392AWS_CRYPTOSDK_STATIC_INLINE
393void aws_cryptosdk_materials_cache_put_entry_for_decrypt(
394 struct aws_cryptosdk_materials_cache *cache,
395 struct aws_cryptosdk_materials_cache_entry **entry,
396 const struct aws_cryptosdk_dec_materials *dec_materials,
397 const struct aws_byte_buf *cache_id) {
398 void (*put_entry_for_decrypt)(
399 struct aws_cryptosdk_materials_cache * cache,
400 struct aws_cryptosdk_materials_cache_entry * *entry,
401 const struct aws_cryptosdk_dec_materials *dec_materials,
402 const struct aws_byte_buf *cache_id) = AWS_CRYPTOSDK_PRIVATE_VT_GET_NULL(cache->vt, put_entry_for_decrypt);
403
404 *entry = NULL;
405 if (put_entry_for_decrypt) {
406 put_entry_for_decrypt(cache, entry, dec_materials, cache_id);
407 }
408}
409
410AWS_CRYPTOSDK_STATIC_INLINE
411void aws_cryptosdk_materials_cache_entry_release(
412 struct aws_cryptosdk_materials_cache *cache, struct aws_cryptosdk_materials_cache_entry *entry, bool invalidate) {
413 void (*entry_release)(
414 struct aws_cryptosdk_materials_cache * cache,
415 struct aws_cryptosdk_materials_cache_entry * entry,
416 bool invalidate) = AWS_CRYPTOSDK_PRIVATE_VT_GET_NULL(cache->vt, entry_release);
417
418 if (entry_release) {
419 entry_release(cache, entry, invalidate);
420 }
421}
422
423AWS_CRYPTOSDK_STATIC_INLINE
424uint64_t aws_cryptosdk_materials_cache_entry_get_creation_time(
425 const struct aws_cryptosdk_materials_cache *cache, const struct aws_cryptosdk_materials_cache_entry *entry) {
426 uint64_t (*entry_get_creation_time)(
427 const struct aws_cryptosdk_materials_cache *cache, const struct aws_cryptosdk_materials_cache_entry *entry) =
428 AWS_CRYPTOSDK_PRIVATE_VT_GET_NULL(cache->vt, entry_get_creation_time);
429
430 if (entry_get_creation_time) {
431 return entry_get_creation_time(cache, entry);
432 } else {
433 return 0;
434 }
435}
436
437AWS_CRYPTOSDK_STATIC_INLINE
438void aws_cryptosdk_materials_cache_entry_ttl_hint(
439 struct aws_cryptosdk_materials_cache *cache, struct aws_cryptosdk_materials_cache_entry *entry, uint64_t exp_time) {
440 void (*entry_ttl_hint)(
441 struct aws_cryptosdk_materials_cache * cache,
442 struct aws_cryptosdk_materials_cache_entry * entry,
443 uint64_t exp_time) = AWS_CRYPTOSDK_PRIVATE_VT_GET_NULL(cache->vt, entry_ttl_hint);
444
445 if (entry_ttl_hint) {
446 entry_ttl_hint(cache, entry, exp_time);
447 }
448}
449
450#endif // AWS_CRYPTOSDK_DOXYGEN (unstable APIs excluded from docs)
451
456AWS_CRYPTOSDK_API
457struct aws_cryptosdk_materials_cache *aws_cryptosdk_materials_cache_local_new(
458 struct aws_allocator *alloc, size_t capacity);
459
464AWS_CRYPTOSDK_STATIC_INLINE
465size_t aws_cryptosdk_materials_cache_entry_count(const struct aws_cryptosdk_materials_cache *cache) {
466 size_t (*entry_count)(const struct aws_cryptosdk_materials_cache *cache) =
467 AWS_CRYPTOSDK_PRIVATE_VT_GET_NULL(cache->vt, entry_count);
468
469 if (!entry_count) {
470 return SIZE_MAX;
471 }
472
473 return entry_count(cache);
474}
475
480AWS_CRYPTOSDK_STATIC_INLINE
481void aws_cryptosdk_materials_cache_clear(struct aws_cryptosdk_materials_cache *cache) {
482 void (*clear)(struct aws_cryptosdk_materials_cache * cache) = AWS_CRYPTOSDK_PRIVATE_VT_GET_NULL(cache->vt, clear);
483
484 if (clear) {
485 clear(cache);
486 }
487}
488
492AWS_CRYPTOSDK_STATIC_INLINE struct aws_cryptosdk_materials_cache *aws_cryptosdk_materials_cache_retain(
493 struct aws_cryptosdk_materials_cache *materials_cache) {
494 aws_cryptosdk_private_refcount_up(&materials_cache->refcount);
495 return materials_cache;
496}
497
501AWS_CRYPTOSDK_STATIC_INLINE void aws_cryptosdk_materials_cache_release(
502 struct aws_cryptosdk_materials_cache *materials_cache) {
503 if (materials_cache && aws_cryptosdk_private_refcount_down(&materials_cache->refcount)) {
504 void (*destroy)(struct aws_cryptosdk_materials_cache * cache) =
505 AWS_CRYPTOSDK_PRIVATE_VT_GET_NULL(materials_cache->vt, destroy);
506
507 if (!destroy) {
508 abort();
509 }
510
511 destroy(materials_cache);
512 }
513}
514
535AWS_CRYPTOSDK_API
537 struct aws_allocator *alloc,
538 struct aws_cryptosdk_materials_cache *materials_cache,
539 struct aws_cryptosdk_cmm *upstream,
540 const struct aws_byte_buf *partition_id,
541 uint64_t cache_limit_ttl,
542 enum aws_timestamp_unit cache_limit_ttl_units);
543
565AWS_CRYPTOSDK_API
567 struct aws_allocator *alloc,
568 struct aws_cryptosdk_materials_cache *materials_cache,
569 struct aws_cryptosdk_keyring *keyring,
570 const struct aws_byte_buf *partition_id,
571 uint64_t cache_limit_ttl,
572 enum aws_timestamp_unit cache_limit_ttl_units);
573
577AWS_CRYPTOSDK_API
578int aws_cryptosdk_caching_cmm_set_ttl(struct aws_cryptosdk_cmm *cmm, uint64_t ttl, enum aws_timestamp_unit ttl_units);
579
584AWS_CRYPTOSDK_API
586
591AWS_CRYPTOSDK_API
592int aws_cryptosdk_caching_cmm_set_limit_messages(struct aws_cryptosdk_cmm *cmm, uint64_t limit_messages);
593
594AWS_EXTERN_C_END
595 // doxygen group caching
597
598#endif
struct aws_cryptosdk_materials_cache * aws_cryptosdk_materials_cache_local_new(struct aws_allocator *alloc, size_t capacity)
int aws_cryptosdk_caching_cmm_set_ttl(struct aws_cryptosdk_cmm *cmm, uint64_t ttl, enum aws_timestamp_unit ttl_units)
size_t aws_cryptosdk_materials_cache_entry_count(const struct aws_cryptosdk_materials_cache *cache)
Definition cache.h:465
struct aws_cryptosdk_cmm * aws_cryptosdk_caching_cmm_new_from_cmm(struct aws_allocator *alloc, struct aws_cryptosdk_materials_cache *materials_cache, struct aws_cryptosdk_cmm *upstream, const struct aws_byte_buf *partition_id, uint64_t cache_limit_ttl, enum aws_timestamp_unit cache_limit_ttl_units)
void aws_cryptosdk_materials_cache_release(struct aws_cryptosdk_materials_cache *materials_cache)
Definition cache.h:501
struct aws_cryptosdk_cmm * aws_cryptosdk_caching_cmm_new_from_keyring(struct aws_allocator *alloc, struct aws_cryptosdk_materials_cache *materials_cache, struct aws_cryptosdk_keyring *keyring, const struct aws_byte_buf *partition_id, uint64_t cache_limit_ttl, enum aws_timestamp_unit cache_limit_ttl_units)
struct aws_cryptosdk_materials_cache * aws_cryptosdk_materials_cache_retain(struct aws_cryptosdk_materials_cache *materials_cache)
Definition cache.h:492
int aws_cryptosdk_caching_cmm_set_limit_bytes(struct aws_cryptosdk_cmm *cmm, uint64_t limit_bytes)
void aws_cryptosdk_materials_cache_clear(struct aws_cryptosdk_materials_cache *cache)
Definition cache.h:481
int aws_cryptosdk_caching_cmm_set_limit_messages(struct aws_cryptosdk_cmm *cmm, uint64_t limit_messages)