-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add CBMC proof for default_cmm_generate_enc_materials #656
Changes from all commits
073a17c
d6cdba9
d9c49a2
ffde1fb
a2179de
fd997a6
c014f30
3104993
8042c35
2c8da7d
3a9d3c7
90f4d45
ecec9b5
73ccb76
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"). You may not use | ||
# this file except in compliance with the License. A copy of the License is | ||
# located at | ||
# | ||
# http://aws.amazon.com/apache2.0/ | ||
# | ||
# or in the "license" file accompanying this file. This file is distributed on an | ||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
# implied. See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
######### | ||
# if Makefile.local exists, use it. This provides a way to override the defaults | ||
sinclude ../Makefile.local | ||
#otherwise, use the default values | ||
include ../Makefile.local_default | ||
include ../Makefile.string | ||
######### | ||
# Local vars | ||
# Values are chosen for performance. Increasing them does not improve coverage. | ||
MAX_TABLE_SIZE ?= 1 | ||
# In OBJ_txt2nid, this value unwinds strcmp(s, "prime256v1") | ||
PRIME_STRING_LEN=10 | ||
######### | ||
PROOF_UID = default_cmm_generate_enc_materials | ||
HARNESS_ENTRY = $(PROOF_UID)_harness | ||
HARNESS_FILE = $(HARNESS_ENTRY).c | ||
|
||
CBMCFLAGS += | ||
|
||
DEFINES += -DMAX_TABLE_SIZE=$(MAX_TABLE_SIZE) | ||
|
||
PROJECT_SOURCES += $(CBMC_ROOT)/aws-c-common/source/byte_buf.c | ||
PROJECT_SOURCES += $(CBMC_ROOT)/aws-c-common/source/common.c | ||
PROJECT_SOURCES += $(CBMC_ROOT)/aws-c-common/source/encoding.c | ||
PROJECT_SOURCES += $(CBMC_ROOT)/aws-c-common/source/error.c | ||
PROJECT_SOURCES += $(CBMC_ROOT)/aws-c-common/source/hash_table.c | ||
PROJECT_SOURCES += $(CBMC_ROOT)/aws-c-common/source/string.c | ||
PROJECT_SOURCES += $(PROOF_SOURCE)/openssl/bn_override.c | ||
PROJECT_SOURCES += $(PROOF_SOURCE)/openssl/ec_override.c | ||
PROJECT_SOURCES += $(PROOF_SOURCE)/openssl/evp_override.c | ||
PROJECT_SOURCES += $(PROOF_SOURCE)/openssl/objects_override.c | ||
PROJECT_SOURCES += $(SRCDIR)/source/cipher.c | ||
PROJECT_SOURCES += $(SRCDIR)/source/cipher_openssl.c | ||
PROJECT_SOURCES += $(SRCDIR)/source/default_cmm.c | ||
PROJECT_SOURCES += $(SRCDIR)/source/edk.c | ||
PROJECT_SOURCES += $(SRCDIR)/source/header.c | ||
PROJECT_SOURCES += $(SRCDIR)/source/keyring_trace.c | ||
PROJECT_SOURCES += $(SRCDIR)/source/materials.c | ||
|
||
PROOF_SOURCES += $(COMMON_PROOF_SOURCE)/make_common_data_structures.c | ||
PROOF_SOURCES += $(COMMON_PROOF_SOURCE)/proof_allocators.c | ||
PROOF_SOURCES += $(COMMON_PROOF_SOURCE)/utils.c | ||
PROOF_SOURCES += $(COMMON_PROOF_STUB)/aws_hash_table_no_slots_override.c | ||
PROOF_SOURCES += $(COMMON_PROOF_STUB)/aws_string_destroy_override.c | ||
PROOF_SOURCES += $(COMMON_PROOF_STUB)/error.c | ||
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE) | ||
PROOF_SOURCES += $(PROOF_SOURCE)/cbmc_invariants.c | ||
PROOF_SOURCES += $(PROOF_SOURCE)/make_common_data_structures.c | ||
PROOF_SOURCES += $(PROOF_STUB)/aws_base64_encode.c | ||
PROOF_SOURCES += $(PROOF_STUB)/on_encrypt_stub.c | ||
|
||
UNWINDSET += strcmp.0:$(call addone,$(PRIME_STRING_LEN)) | ||
########### | ||
include ../Makefile.common |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
: | ||
This file marks this directory as containing a CBMC proof. This file | ||
is automatically clobbered in CI and replaced with parameters for | ||
running the proof. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"). You may not | ||
* use | ||
* this file except in compliance with the License. A copy of the License is | ||
* located at | ||
* | ||
* http://aws.amazon.com/apache2.0/ | ||
* | ||
* or in the "license" file accompanying this file. This file is distributed on | ||
* an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or | ||
* implied. See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include <aws/cryptosdk/default_cmm.h> | ||
#include <aws/cryptosdk/materials.h> | ||
#include <make_common_data_structures.h> | ||
|
||
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); | ||
|
||
void default_cmm_generate_enc_materials_harness() { | ||
const struct aws_cryptosdk_keyring_vt vtable = { .vt_size = nondet_size_t(), | ||
.name = ensure_c_str_is_allocated(SIZE_MAX), | ||
.destroy = nondet_voidp(), | ||
.on_encrypt = nondet_bool() ? NULL : on_encrypt, | ||
.on_decrypt = nondet_voidp() }; | ||
/* Nondet input */ | ||
struct aws_cryptosdk_cmm *cmm = ensure_default_cmm_attempt_allocation(&vtable); | ||
struct aws_cryptosdk_enc_materials *output = ensure_enc_materials_attempt_allocation(); | ||
struct aws_cryptosdk_enc_request *request = ensure_enc_request_attempt_allocation(MAX_TABLE_SIZE); | ||
|
||
/* Assumptions */ | ||
__CPROVER_assume(aws_cryptosdk_default_cmm_is_valid(cmm)); | ||
|
||
__CPROVER_assume(output != NULL); | ||
|
||
__CPROVER_assume(aws_cryptosdk_enc_request_is_valid(request)); | ||
|
||
/* Save current state of the data structures */ | ||
struct store_byte_from_buffer old_output; | ||
save_byte_from_array((uint8_t *)output, sizeof(*output), &old_output); | ||
|
||
/* Operation under verification */ | ||
if (__CPROVER_file_local_default_cmm_c_default_cmm_generate_enc_materials(cmm, &output, request) == | ||
AWS_OP_SUCCESS) { | ||
assert(aws_cryptosdk_enc_materials_is_valid(output)); | ||
assert(aws_cryptosdk_algorithm_is_known(request->requested_alg)); | ||
} else { | ||
/* Note that we perform a top-level comparison here */ | ||
assert_byte_from_buffer_matches((uint8_t *)output, &old_output); | ||
} | ||
|
||
/* Postconditions */ | ||
assert(aws_cryptosdk_default_cmm_is_valid(cmm)); | ||
assert(aws_cryptosdk_enc_request_is_valid(request)); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ | |
*/ | ||
|
||
#include <aws/cryptosdk/cipher.h> | ||
#include <aws/cryptosdk/default_cmm.h> | ||
#include <aws/cryptosdk/keyring_trace.h> | ||
#include <aws/cryptosdk/materials.h> | ||
#include <aws/cryptosdk/private/header.h> | ||
|
@@ -31,6 +32,14 @@ | |
#include <proof_helpers/make_common_data_structures.h> | ||
#include <proof_helpers/proof_allocators.h> | ||
|
||
struct default_cmm { | ||
struct aws_cryptosdk_cmm base; | ||
struct aws_allocator *alloc; | ||
struct aws_cryptosdk_keyring *kr; | ||
/* Invariant: this is either DEFAULT_ALG_UNSET or is a valid algorithm ID */ | ||
enum aws_cryptosdk_alg_id default_alg; | ||
}; | ||
|
||
const EVP_MD *nondet_EVP_MD_ptr(void); | ||
const EVP_CIPHER *nondet_EVP_CIPHER_ptr(void); | ||
|
||
|
@@ -346,6 +355,7 @@ bool aws_cryptosdk_dec_materials_members_are_bounded( | |
} | ||
return true; | ||
} | ||
|
||
struct aws_cryptosdk_dec_materials *ensure_dec_materials_attempt_allocation() { | ||
struct aws_cryptosdk_dec_materials *materials = malloc(sizeof(struct aws_cryptosdk_dec_materials)); | ||
if (materials) { | ||
|
@@ -369,4 +379,51 @@ struct aws_cryptosdk_dec_materials *dec_materials_setup( | |
} | ||
__CPROVER_assume(aws_cryptosdk_dec_materials_is_valid(materials)); | ||
return materials; | ||
} | ||
} | ||
|
||
struct aws_cryptosdk_enc_request *ensure_enc_request_attempt_allocation(const size_t max_table_size) { | ||
struct aws_cryptosdk_enc_request *request = malloc(sizeof(struct aws_cryptosdk_enc_request)); | ||
if (request) { | ||
request->alloc = nondet_bool() ? NULL : can_fail_allocator(); | ||
request->enc_ctx = malloc(sizeof(struct aws_hash_table)); | ||
if (request->enc_ctx) { | ||
ensure_allocated_hash_table(request->enc_ctx, max_table_size); | ||
} | ||
} | ||
return request; | ||
} | ||
|
||
struct aws_cryptosdk_enc_materials *ensure_enc_materials_attempt_allocation() { | ||
struct aws_cryptosdk_enc_materials *materials = malloc(sizeof(struct aws_cryptosdk_enc_materials)); | ||
if (materials) { | ||
materials->alloc = nondet_bool() ? NULL : can_fail_allocator(); | ||
materials->signctx = ensure_nondet_sig_ctx_has_allocated_members(); | ||
ensure_byte_buf_has_allocated_buffer_member(&materials->encrypted_data_keys); | ||
ensure_array_list_has_allocated_data_member(&materials->keyring_trace); | ||
ensure_array_list_has_allocated_data_member(&materials->encrypted_data_keys); | ||
} | ||
return materials; | ||
} | ||
|
||
struct aws_cryptosdk_cmm *ensure_default_cmm_attempt_allocation(const struct aws_cryptosdk_keyring_vt *vtable) { | ||
/* Nondet input required to init cmm */ | ||
struct aws_cryptosdk_keyring *keyring = malloc(sizeof(*keyring)); | ||
|
||
/* Assumptions required to init cmm */ | ||
ensure_cryptosdk_keyring_has_allocated_members(keyring, vtable); | ||
__CPROVER_assume(aws_cryptosdk_keyring_is_valid(keyring)); | ||
__CPROVER_assume(keyring->vtable != NULL); | ||
Comment on lines
+412
to
+415
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Create a GitHub issue to investigate a way to move these assumptions to the validity function and not to the allocator. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Opened one here: #675 |
||
|
||
struct aws_cryptosdk_cmm *cmm = malloc(sizeof(struct default_cmm)); | ||
if (cmm) { | ||
cmm->vtable = vtable; | ||
} | ||
|
||
struct default_cmm *self = NULL; | ||
if (cmm) { | ||
self = (struct default_cmm *)cmm; | ||
self->alloc = nondet_bool() ? NULL : can_fail_allocator(); | ||
self->kr = keyring; | ||
} | ||
return (struct aws_cryptosdk_cmm *)self; | ||
Comment on lines
+422
to
+428
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why? |
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this function wasn't written like...
Shouldn't we validate both structures separately (i.e., on validity function for each data structure)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, extensions of
aws_cryptosdk_cmm
are always handled like this in the source code: The type is used as a parameter/return type and the struct is cast before doing any operations on it. This way, we are following API guidelines.I am not sure what you mean by "validate both structures separately". We have
aws_cryptosdk_cmm_base_is_valid
for validatingaws_cryptosdk_cmm
structs and this one to validatedefault_cmm
structs.