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>
167 return request && aws_allocator_is_valid(request->
alloc) && aws_hash_table_is_valid(request->
enc_ctx);
196 return request && aws_allocator_is_valid(request->
alloc) &&
215 if (!AWS_OBJECT_PTR_IS_WRITABLE(materials)) {
218 bool allocator_valid = aws_allocator_is_valid(materials->
alloc);
223 return allocator_valid && unencrypted_data_key_valid && keyring_trace_valid && encrypted_data_keys_valid &&
229 if (!AWS_OBJECT_PTR_IS_WRITABLE(materials)) {
232 bool allocator_valid = aws_allocator_is_valid(materials->
alloc);
236 return allocator_valid && unencrypted_data_key_valid && keyring_trace_valid && signctx_valid;
239#ifndef AWS_CRYPTOSDK_DOXYGEN
249# define AWS_CRYPTOSDK_PRIVATE_STRUCT_NAME(...) AWS_CRYPTOSDK_PRIVATE_STRUCT_NAME_2((__VA_ARGS__, throwaway))
250# define AWS_CRYPTOSDK_PRIVATE_STRUCT_NAME_2(args) AWS_CRYPTOSDK_PRIVATE_STRUCT_NAME_3 args
251# define AWS_CRYPTOSDK_PRIVATE_STRUCT_NAME_3(struct_type, ...) struct_type
253# define AWS_CRYPTOSDK_PRIVATE_BASE_TYPE(...) AWS_CRYPTOSDK_PRIVATE_BASE_TYPE_2((__VA_ARGS__, throwaway))
254# define AWS_CRYPTOSDK_PRIVATE_BASE_TYPE_2(args) AWS_CRYPTOSDK_PRIVATE_BASE_TYPE_3 args
255# define AWS_CRYPTOSDK_PRIVATE_BASE_TYPE_3(struct_type, ...) const struct aws_cryptosdk_##struct_type
267# define AWS_CRYPTOSDK_PRIVATE_VF_CALL(fn_name, ...) \
270 AWS_CRYPTOSDK_PRIVATE_BASE_TYPE(__VA_ARGS__) *pbase = \
271 (AWS_CRYPTOSDK_PRIVATE_BASE_TYPE(__VA_ARGS__) *)AWS_CRYPTOSDK_PRIVATE_STRUCT_NAME(__VA_ARGS__); \
272 ptrdiff_t memb_offset = (const uint8_t *)&(pbase->vtable)->fn_name - (const uint8_t *)pbase->vtable; \
273 if (memb_offset + sizeof((pbase->vtable)->fn_name) > (pbase->vtable)->vt_size || \
274 !(pbase->vtable)->fn_name) { \
275 return aws_raise_error(AWS_ERROR_UNIMPLEMENTED); \
277 ret = (pbase->vtable)->fn_name(__VA_ARGS__); \
285# define AWS_CRYPTOSDK_PRIVATE_VF_CALL_NO_RETURN(fn_name, ...) \
287 AWS_CRYPTOSDK_PRIVATE_BASE_TYPE(__VA_ARGS__) *pbase = \
288 (AWS_CRYPTOSDK_PRIVATE_BASE_TYPE(__VA_ARGS__) *)AWS_CRYPTOSDK_PRIVATE_STRUCT_NAME(__VA_ARGS__); \
289 ptrdiff_t memb_offset = (const uint8_t *)&(pbase->vtable)->fn_name - (const uint8_t *)pbase->vtable; \
290 if (memb_offset + sizeof((pbase->vtable)->fn_name) > (pbase->vtable)->vt_size || \
291 !(pbase->vtable)->fn_name) { \
292 aws_raise_error(AWS_ERROR_UNIMPLEMENTED); \
294 (pbase->vtable)->fn_name(__VA_ARGS__); \
301AWS_CRYPTOSDK_STATIC_INLINE
bool aws_cryptosdk_private_refcount_down(
struct aws_atomic_var *refcount) {
326 size_t old_count = aws_atomic_fetch_sub_explicit(refcount, 1, aws_memory_order_acq_rel);
328 assert(old_count != 0);
330 return old_count == 1;
336AWS_CRYPTOSDK_STATIC_INLINE
void aws_cryptosdk_private_refcount_up(
struct aws_atomic_var *refcount) {
356 size_t old_count = aws_atomic_fetch_add_explicit(refcount, 1, aws_memory_order_relaxed);
358 assert(old_count != 0 && old_count != SIZE_MAX);
404 return AWS_MEM_IS_WRITABLE(var,
sizeof(
size_t));
411 return AWS_OBJECT_PTR_IS_WRITABLE(var) && AWS_OBJECT_PTR_IS_WRITABLE((
size_t *)aws_atomic_load_ptr(var));
419 aws_c_string_is_valid(vtable->
name);
428 aws_atomic_load_int(&cmm->
refcount) > 0 && aws_atomic_load_int(&cmm->
refcount) <= SIZE_MAX &&
438 AWS_PRECONDITION(AWS_OBJECT_PTR_IS_WRITABLE(cmm));
441 aws_atomic_init_int(&cmm->
refcount, 1);
451 if (cmm && aws_cryptosdk_private_refcount_down(&cmm->
refcount)) {
452 AWS_CRYPTOSDK_PRIVATE_VF_CALL_NO_RETURN(
destroy, cmm);
462 AWS_PRECONDITION(aws_atomic_load_int(&cmm->
refcount) < SIZE_MAX);
463 aws_cryptosdk_private_refcount_up(&cmm->
refcount);
486 AWS_ERROR_PRECONDITION(output == NULL || AWS_OBJECT_PTR_IS_WRITABLE(output));
488 AWS_CRYPTOSDK_PRIVATE_VF_CALL(generate_enc_materials, cmm, output, request);
509 AWS_ERROR_PRECONDITION(output == NULL || AWS_OBJECT_PTR_IS_WRITABLE(output));
512 AWS_CRYPTOSDK_PRIVATE_VF_CALL(decrypt_materials, cmm, output, request);
542 struct aws_allocator *request_alloc,
543 struct aws_byte_buf *unencrypted_data_key,
544 struct aws_array_list *keyring_trace,
545 struct aws_array_list *edks,
546 const struct aws_hash_table *enc_ctx,
559 struct aws_allocator *request_alloc,
560 struct aws_byte_buf *unencrypted_data_key,
561 struct aws_array_list *keyring_trace,
562 const struct aws_array_list *edks,
563 const struct aws_hash_table *enc_ctx,
571 return AWS_OBJECT_PTR_IS_READABLE(vtable) && aws_c_string_is_valid(vtable->
name) &&
581 (aws_atomic_load_int(&keyring->
refcount) > 0) && (aws_atomic_load_int(&keyring->
refcount) <= SIZE_MAX) &&
591 AWS_PRECONDITION(keyring != NULL);
593 AWS_PRECONDITION(vtable == NULL || aws_c_string_is_valid(vtable->
name));
595 aws_atomic_init_int(&keyring->
refcount, 1);
604 if (keyring && aws_cryptosdk_private_refcount_down(&keyring->
refcount)) {
605 AWS_CRYPTOSDK_PRIVATE_VF_CALL_NO_RETURN(
destroy, keyring);
617 AWS_PRECONDITION(aws_atomic_load_int(&keyring->
refcount) < SIZE_MAX);
618 aws_cryptosdk_private_refcount_up(&keyring->
refcount);
641 struct aws_allocator *request_alloc,
642 struct aws_byte_buf *unencrypted_data_key,
643 struct aws_array_list *keyring_trace,
644 struct aws_array_list *edks,
645 const struct aws_hash_table *enc_ctx,
663 struct aws_allocator *request_alloc,
664 struct aws_byte_buf *unencrypted_data_key,
665 struct aws_array_list *keyring_trace,
666 const struct aws_array_list *edks,
667 const struct aws_hash_table *enc_ctx,
713 switch (commitment_policy) {
717 default:
return false;
727 switch (commitment_policy) {
731 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