16#ifndef AWS_CRYPTOSDK_MATERIALS_H
17#define AWS_CRYPTOSDK_MATERIALS_H
23#include <aws/common/array_list.h>
24#include <aws/common/atomics.h>
25#include <aws/common/byte_buf.h>
26#include <aws/common/common.h>
27#include <aws/common/hash_table.h>
32#include <aws/cryptosdk/exports.h>
177 return request && aws_allocator_is_valid(request->
alloc) && aws_hash_table_is_valid(request->
enc_ctx);
221 return request && aws_allocator_is_valid(request->
alloc) &&
240 if (!AWS_OBJECT_PTR_IS_WRITABLE(materials)) {
243 bool allocator_valid = aws_allocator_is_valid(materials->
alloc);
248 return allocator_valid && unencrypted_data_key_valid && keyring_trace_valid && encrypted_data_keys_valid &&
254 if (!AWS_OBJECT_PTR_IS_WRITABLE(materials)) {
257 bool allocator_valid = aws_allocator_is_valid(materials->
alloc);
261 return allocator_valid && unencrypted_data_key_valid && keyring_trace_valid && signctx_valid;
264#ifndef AWS_CRYPTOSDK_DOXYGEN
274# define AWS_CRYPTOSDK_PRIVATE_STRUCT_NAME(...) AWS_CRYPTOSDK_PRIVATE_STRUCT_NAME_2((__VA_ARGS__, throwaway))
275# define AWS_CRYPTOSDK_PRIVATE_STRUCT_NAME_2(args) AWS_CRYPTOSDK_PRIVATE_STRUCT_NAME_3 args
276# define AWS_CRYPTOSDK_PRIVATE_STRUCT_NAME_3(struct_type, ...) struct_type
278# define AWS_CRYPTOSDK_PRIVATE_BASE_TYPE(...) AWS_CRYPTOSDK_PRIVATE_BASE_TYPE_2((__VA_ARGS__, throwaway))
279# define AWS_CRYPTOSDK_PRIVATE_BASE_TYPE_2(args) AWS_CRYPTOSDK_PRIVATE_BASE_TYPE_3 args
280# define AWS_CRYPTOSDK_PRIVATE_BASE_TYPE_3(struct_type, ...) const struct aws_cryptosdk_##struct_type
292# define AWS_CRYPTOSDK_PRIVATE_VF_CALL(fn_name, ...) \
295 AWS_CRYPTOSDK_PRIVATE_BASE_TYPE(__VA_ARGS__) *pbase = \
296 (AWS_CRYPTOSDK_PRIVATE_BASE_TYPE(__VA_ARGS__) *)AWS_CRYPTOSDK_PRIVATE_STRUCT_NAME(__VA_ARGS__); \
297 ptrdiff_t memb_offset = (const uint8_t *)&(pbase->vtable)->fn_name - (const uint8_t *)pbase->vtable; \
298 if (memb_offset + sizeof((pbase->vtable)->fn_name) > (pbase->vtable)->vt_size || \
299 !(pbase->vtable)->fn_name) { \
300 return aws_raise_error(AWS_ERROR_UNIMPLEMENTED); \
302 ret = (pbase->vtable)->fn_name(__VA_ARGS__); \
310# define AWS_CRYPTOSDK_PRIVATE_VF_CALL_NO_RETURN(fn_name, ...) \
312 AWS_CRYPTOSDK_PRIVATE_BASE_TYPE(__VA_ARGS__) *pbase = \
313 (AWS_CRYPTOSDK_PRIVATE_BASE_TYPE(__VA_ARGS__) *)AWS_CRYPTOSDK_PRIVATE_STRUCT_NAME(__VA_ARGS__); \
314 ptrdiff_t memb_offset = (const uint8_t *)&(pbase->vtable)->fn_name - (const uint8_t *)pbase->vtable; \
315 if (memb_offset + sizeof((pbase->vtable)->fn_name) > (pbase->vtable)->vt_size || \
316 !(pbase->vtable)->fn_name) { \
317 aws_raise_error(AWS_ERROR_UNIMPLEMENTED); \
319 (pbase->vtable)->fn_name(__VA_ARGS__); \
326AWS_CRYPTOSDK_STATIC_INLINE
bool aws_cryptosdk_private_refcount_down(
struct aws_atomic_var *refcount) {
351 size_t old_count = aws_atomic_fetch_sub_explicit(refcount, 1, aws_memory_order_acq_rel);
353 assert(old_count != 0);
355 return old_count == 1;
361AWS_CRYPTOSDK_STATIC_INLINE
void aws_cryptosdk_private_refcount_up(
struct aws_atomic_var *refcount) {
381 size_t old_count = aws_atomic_fetch_add_explicit(refcount, 1, aws_memory_order_relaxed);
383 assert(old_count != 0 && old_count != SIZE_MAX);
429 return AWS_MEM_IS_WRITABLE(var,
sizeof(
size_t));
436 return AWS_OBJECT_PTR_IS_WRITABLE(var) && AWS_OBJECT_PTR_IS_WRITABLE((
size_t *)aws_atomic_load_ptr(var));
444 aws_c_string_is_valid(vtable->
name);
453 aws_atomic_load_int(&cmm->
refcount) > 0 && aws_atomic_load_int(&cmm->
refcount) <= SIZE_MAX &&
463 AWS_PRECONDITION(AWS_OBJECT_PTR_IS_WRITABLE(cmm));
466 aws_atomic_init_int(&cmm->
refcount, 1);
476 if (cmm && aws_cryptosdk_private_refcount_down(&cmm->
refcount)) {
477 AWS_CRYPTOSDK_PRIVATE_VF_CALL_NO_RETURN(
destroy, cmm);
487 AWS_PRECONDITION(aws_atomic_load_int(&cmm->
refcount) < SIZE_MAX);
488 aws_cryptosdk_private_refcount_up(&cmm->
refcount);
511 AWS_ERROR_PRECONDITION(output == NULL || AWS_OBJECT_PTR_IS_WRITABLE(output));
513 AWS_CRYPTOSDK_PRIVATE_VF_CALL(generate_enc_materials, cmm, output, request);
534 AWS_ERROR_PRECONDITION(output == NULL || AWS_OBJECT_PTR_IS_WRITABLE(output));
537 AWS_CRYPTOSDK_PRIVATE_VF_CALL(decrypt_materials, cmm, output, request);
567 struct aws_allocator *request_alloc,
568 struct aws_byte_buf *unencrypted_data_key,
569 struct aws_array_list *keyring_trace,
570 struct aws_array_list *edks,
571 const struct aws_hash_table *enc_ctx,
584 struct aws_allocator *request_alloc,
585 struct aws_byte_buf *unencrypted_data_key,
586 struct aws_array_list *keyring_trace,
587 const struct aws_array_list *edks,
588 const struct aws_hash_table *enc_ctx,
596 return AWS_OBJECT_PTR_IS_READABLE(vtable) && aws_c_string_is_valid(vtable->
name) &&
606 (aws_atomic_load_int(&keyring->
refcount) > 0) && (aws_atomic_load_int(&keyring->
refcount) <= SIZE_MAX) &&
616 AWS_PRECONDITION(keyring != NULL);
618 AWS_PRECONDITION(vtable == NULL || aws_c_string_is_valid(vtable->
name));
620 aws_atomic_init_int(&keyring->
refcount, 1);
629 if (keyring && aws_cryptosdk_private_refcount_down(&keyring->
refcount)) {
630 AWS_CRYPTOSDK_PRIVATE_VF_CALL_NO_RETURN(
destroy, keyring);
642 AWS_PRECONDITION(aws_atomic_load_int(&keyring->
refcount) < SIZE_MAX);
643 aws_cryptosdk_private_refcount_up(&keyring->
refcount);
666 struct aws_allocator *request_alloc,
667 struct aws_byte_buf *unencrypted_data_key,
668 struct aws_array_list *keyring_trace,
669 struct aws_array_list *edks,
670 const struct aws_hash_table *enc_ctx,
688 struct aws_allocator *request_alloc,
689 struct aws_byte_buf *unencrypted_data_key,
690 struct aws_array_list *keyring_trace,
691 const struct aws_array_list *edks,
692 const struct aws_hash_table *enc_ctx,
738 switch (commitment_policy) {
742 default:
return false;
752 switch (commitment_policy) {
756 default:
return false;
struct aws_cryptosdk_cmm * aws_cryptosdk_cmm_retain(struct aws_cryptosdk_cmm *cmm)
struct aws_cryptosdk_keyring * aws_cryptosdk_keyring_retain(struct aws_cryptosdk_keyring *keyring)
void aws_cryptosdk_keyring_release(struct aws_cryptosdk_keyring *keyring)
void aws_cryptosdk_cmm_release(struct aws_cryptosdk_cmm *cmm)
int aws_cryptosdk_keyring_on_encrypt(struct aws_cryptosdk_keyring *keyring, struct aws_allocator *request_alloc, struct aws_byte_buf *unencrypted_data_key, struct aws_array_list *keyring_trace, struct aws_array_list *edks, const struct aws_hash_table *enc_ctx, enum aws_cryptosdk_alg_id alg)
int aws_cryptosdk_cmm_generate_enc_materials(struct aws_cryptosdk_cmm *cmm, struct aws_cryptosdk_enc_materials **output, struct aws_cryptosdk_enc_request *request)
int aws_cryptosdk_cmm_decrypt_materials(struct aws_cryptosdk_cmm *cmm, struct aws_cryptosdk_dec_materials **output, struct aws_cryptosdk_dec_request *request)
int aws_cryptosdk_keyring_on_decrypt(struct aws_cryptosdk_keyring *keyring, struct aws_allocator *request_alloc, struct aws_byte_buf *unencrypted_data_key, struct aws_array_list *keyring_trace, const struct aws_array_list *edks, const struct aws_hash_table *enc_ctx, enum aws_cryptosdk_alg_id alg)
aws_cryptosdk_commitment_policy
bool aws_cryptosdk_cmm_vtable_is_valid(const struct aws_cryptosdk_cmm_vt *vtable)
bool aws_cryptosdk_edk_list_is_valid(const struct aws_array_list *edk_list)
bool aws_cryptosdk_commitment_policy_encrypt_must_include_commitment(enum aws_cryptosdk_commitment_policy commitment_policy)
bool aws_cryptosdk_enc_request_is_valid(const struct aws_cryptosdk_enc_request *request)
bool aws_atomic_var_is_valid_ptr(const struct aws_atomic_var *var)
bool aws_cryptosdk_enc_materials_is_valid(const struct aws_cryptosdk_enc_materials *materials)
void aws_cryptosdk_cmm_base_init(struct aws_cryptosdk_cmm *cmm, const struct aws_cryptosdk_cmm_vt *vtable)
bool aws_cryptosdk_cmm_base_is_valid(const struct aws_cryptosdk_cmm *cmm)
bool aws_cryptosdk_dec_materials_is_valid(const struct aws_cryptosdk_dec_materials *materials)
void aws_cryptosdk_dec_materials_destroy(struct aws_cryptosdk_dec_materials *dec_mat)
bool aws_cryptosdk_keyring_vt_is_valid(const struct aws_cryptosdk_keyring_vt *vtable)
void aws_cryptosdk_keyring_base_init(struct aws_cryptosdk_keyring *keyring, const struct aws_cryptosdk_keyring_vt *vtable)
bool aws_cryptosdk_dec_request_is_valid(const struct aws_cryptosdk_dec_request *request)
struct aws_cryptosdk_enc_materials * aws_cryptosdk_enc_materials_new(struct aws_allocator *alloc, enum aws_cryptosdk_alg_id alg)
bool aws_cryptosdk_keyring_is_valid(const struct aws_cryptosdk_keyring *keyring)
void aws_cryptosdk_enc_materials_destroy(struct aws_cryptosdk_enc_materials *enc_mat)
bool aws_atomic_var_is_valid_int(const struct aws_atomic_var *var)
struct aws_cryptosdk_dec_materials * aws_cryptosdk_dec_materials_new(struct aws_allocator *alloc, enum aws_cryptosdk_alg_id alg)
bool aws_cryptosdk_commitment_policy_is_valid(uint32_t commitment_policy)
@ COMMITMENT_POLICY_REQUIRE_ENCRYPT_REQUIRE_DECRYPT
@ COMMITMENT_POLICY_REQUIRE_ENCRYPT_ALLOW_DECRYPT
@ COMMITMENT_POLICY_FORBID_ENCRYPT_ALLOW_DECRYPT
bool aws_cryptosdk_sig_ctx_is_valid(const struct aws_cryptosdk_sig_ctx *sig_ctx)
bool aws_cryptosdk_keyring_trace_is_valid(const struct aws_array_list *trace)
int(* generate_enc_materials)(struct aws_cryptosdk_cmm *cmm, struct aws_cryptosdk_enc_materials **output, struct aws_cryptosdk_enc_request *request)
int(* decrypt_materials)(struct aws_cryptosdk_cmm *cmm, struct aws_cryptosdk_dec_materials **output, struct aws_cryptosdk_dec_request *request)
void(* destroy)(struct aws_cryptosdk_cmm *cmm)
struct aws_atomic_var refcount
const struct aws_cryptosdk_cmm_vt * vtable
struct aws_allocator * alloc
enum aws_cryptosdk_alg_id alg
struct aws_byte_buf unencrypted_data_key
struct aws_array_list keyring_trace
struct aws_cryptosdk_sig_ctx * signctx
enum aws_cryptosdk_alg_id alg
struct aws_array_list encrypted_data_keys
const struct aws_hash_table * enc_ctx
struct aws_allocator * alloc
struct aws_array_list encrypted_data_keys
struct aws_cryptosdk_sig_ctx * signctx
struct aws_array_list keyring_trace
struct aws_byte_buf unencrypted_data_key
struct aws_allocator * alloc
enum aws_cryptosdk_alg_id alg
struct aws_allocator * alloc
struct aws_hash_table * enc_ctx
enum aws_cryptosdk_commitment_policy commitment_policy
enum aws_cryptosdk_alg_id requested_alg
int(* on_decrypt)(struct aws_cryptosdk_keyring *keyring, struct aws_allocator *request_alloc, struct aws_byte_buf *unencrypted_data_key, struct aws_array_list *keyring_trace, const struct aws_array_list *edks, const struct aws_hash_table *enc_ctx, enum aws_cryptosdk_alg_id alg)
void(* destroy)(struct aws_cryptosdk_keyring *keyring)
int(* on_encrypt)(struct aws_cryptosdk_keyring *keyring, struct aws_allocator *request_alloc, struct aws_byte_buf *unencrypted_data_key, struct aws_array_list *keyring_trace, struct aws_array_list *edks, const struct aws_hash_table *enc_ctx, enum aws_cryptosdk_alg_id alg)
struct aws_atomic_var refcount
const struct aws_cryptosdk_keyring_vt * vtable