/* * 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. */ #include #include bool s2n_blob_is_bounded(const struct s2n_blob *blob, const size_t max_size) { return (blob->size <= max_size); } bool s2n_stuffer_is_bounded(const struct s2n_stuffer *stuffer, const size_t max_size) { return (stuffer->blob.size <= max_size); } void cbmc_populate_s2n_blob(struct s2n_blob *blob) { CBMC_ENSURE_REF(blob); if (blob->growable) { blob->data = (blob->allocated == 0) ? NULL : malloc(blob->allocated); } else { blob->data = (blob->size == 0) ? NULL : malloc(blob->size); } } struct s2n_blob *cbmc_allocate_s2n_blob() { struct s2n_blob *blob = malloc(sizeof(*blob)); cbmc_populate_s2n_blob(blob); return blob; } void cbmc_populate_s2n_stuffer(struct s2n_stuffer *stuffer) { CBMC_ENSURE_REF(stuffer); cbmc_populate_s2n_blob(&stuffer->blob); } struct s2n_stuffer *cbmc_allocate_s2n_stuffer() { struct s2n_stuffer *stuffer = malloc(sizeof(*stuffer)); cbmc_populate_s2n_stuffer(stuffer); return stuffer; } const char *ensure_c_str_is_allocated(size_t max_size) { size_t cap; __CPROVER_assume(cap > 0 && cap <= max_size); const char *str = malloc(cap); /* Ensure that its a valid c string. Since all bytes are nondeterminstic, the actual * string length is 0..str_cap */ __CPROVER_assume(IMPLIES(str != NULL, str[ cap - 1 ] == '\0')); return str; } const char *nondet_c_str_is_allocated(size_t max_size) { size_t cap; __CPROVER_assume(cap > 0 && cap <= max_size); const char *str = malloc(cap); /* Ensure that its a valid c string. Since all bytes are nondeterminstic, the actual * string length is 0..str_cap */ __CPROVER_assume(IMPLIES(str != NULL, str[ cap - 1 ] == 0)); return str; } void cbmc_populate_s2n_stuffer_reservation(struct s2n_stuffer_reservation *reservation) { CBMC_ENSURE_REF(reservation); reservation->stuffer = cbmc_allocate_s2n_stuffer(); } struct s2n_stuffer_reservation *cbmc_allocate_s2n_stuffer_reservation() { struct s2n_stuffer_reservation *reservation = malloc(sizeof(*reservation)); cbmc_populate_s2n_stuffer_reservation(reservation); return reservation; } bool s2n_array_is_bounded(const struct s2n_array *array, const size_t max_len, const size_t max_element_size) { return (array->len <= max_len) && (array->element_size <= max_element_size); } void cbmc_populate_s2n_array(struct s2n_array *array) { CBMC_ENSURE_REF(array); cbmc_populate_s2n_blob(&array->mem); } struct s2n_array *cbmc_allocate_s2n_array() { struct s2n_array *array = malloc(sizeof(*array)); cbmc_populate_s2n_array(array); return array; } bool s2n_set_is_bounded(const struct s2n_set *set, const size_t max_len, const size_t max_element_size) { return s2n_array_is_bounded(set->data, max_len, max_element_size); } static int nondet_comparator(const void *a, const void *b) { __CPROVER_assert(a != NULL, "a is not NULL"); __CPROVER_assert(b != NULL, "b is not NULL"); return nondet_int(); } void cbmc_populate_s2n_set(struct s2n_set *set) { CBMC_ENSURE_REF(set); set->data = cbmc_allocate_s2n_array(); set->comparator = nondet_comparator; } struct s2n_set *cbmc_allocate_s2n_set() { struct s2n_set *set = malloc(sizeof(*set)); cbmc_populate_s2n_set(set); return set; } void cbmc_populate_s2n_dh_params(struct s2n_dh_params *s2n_dh_params) { CBMC_ENSURE_REF(s2n_dh_params); s2n_dh_params->dh = DH_new(); } struct s2n_dh_params *cbmc_allocate_dh_params() { struct s2n_dh_params *dh_params = malloc(sizeof(*dh_params)); cbmc_populate_s2n_dh_params(dh_params); return dh_params; } void cbmc_populate_BIGNUM(BIGNUM *bignum) { CBMC_ENSURE_REF(bignum); bignum->d = malloc(sizeof(*(bignum->d))); } BIGNUM *cbmc_allocate_BIGNUM() { BIGNUM *bignum = malloc(sizeof(*bignum)); cbmc_populate_BIGNUM(bignum); return bignum; } void cbmc_populate_EC_GROUP(EC_GROUP *ec_group) { CBMC_ENSURE_REF(ec_group); ec_group->order = cbmc_allocate_BIGNUM(); } EC_GROUP *cbmc_allocate_EC_GROUP() { EC_GROUP *ec_group = malloc(sizeof(*ec_group)); cbmc_populate_EC_GROUP(ec_group); return ec_group; } void cbmc_populate_EC_KEY(EC_KEY *ec_key) { CBMC_ENSURE_REF(ec_key); ec_key->group = cbmc_allocate_EC_GROUP(); ec_key->priv_key = cbmc_allocate_BIGNUM(); } EC_KEY *cbmc_allocate_EC_KEY() { EC_KEY *ec_key = malloc(sizeof(*ec_key)); cbmc_populate_EC_KEY(ec_key); return ec_key; } void cbmc_populate_EVP_PKEY(EVP_PKEY *evp_pkey) { CBMC_ENSURE_REF(evp_pkey); evp_pkey->ec_key = cbmc_allocate_EC_KEY(); } EVP_PKEY *cbmc_allocate_EVP_PKEY() { EVP_PKEY *evp_pkey = malloc(sizeof(*evp_pkey)); cbmc_populate_EVP_PKEY(evp_pkey); return evp_pkey; } void cbmc_populate_EVP_PKEY_CTX(EVP_PKEY_CTX *evp_pkey_ctx) { CBMC_ENSURE_REF(evp_pkey_ctx); evp_pkey_ctx->pkey = cbmc_allocate_EVP_PKEY(); } EVP_PKEY_CTX *cbmc_allocate_EVP_PKEY_CTX() { EVP_PKEY_CTX *evp_pkey_ctx = malloc(sizeof(*evp_pkey_ctx)); cbmc_populate_EVP_PKEY_CTX(evp_pkey_ctx); return evp_pkey_ctx; } void cbmc_populate_EVP_MD_CTX(EVP_MD_CTX *ctx) { CBMC_ENSURE_REF(ctx); ctx->digest = malloc(sizeof(*(ctx->digest))); ctx->md_data = malloc(EVP_MAX_MD_SIZE); ctx->pctx = cbmc_allocate_EVP_PKEY_CTX(); } EVP_MD_CTX *cbmc_allocate_EVP_MD_CTX() { EVP_MD_CTX *ctx = malloc(sizeof(*ctx)); cbmc_populate_EVP_MD_CTX(ctx); return ctx; } void cbmc_populate_s2n_evp_digest(struct s2n_evp_digest *evp_digest) { CBMC_ENSURE_REF(evp_digest); /* `evp_digest->md` is never allocated. * It is always initialized based on the hashing algorithm. * If required, this initialization should be done in the validation function. */ evp_digest->ctx = cbmc_allocate_EVP_MD_CTX(); } struct s2n_evp_digest* cbmc_allocate_s2n_evp_digest() { struct s2n_evp_digest *evp_digest = malloc(sizeof(*evp_digest)); cbmc_populate_s2n_evp_digest(evp_digest); return evp_digest; } void cbmc_populate_s2n_evp_hmac_state(struct s2n_evp_hmac_state *evp_hmac_state) { CBMC_ENSURE_REF(evp_hmac_state); cbmc_populate_s2n_evp_digest(&(evp_hmac_state->evp_digest)); if (s2n_libcrypto_is_awslc() || s2n_libcrypto_is_boringssl()) { evp_hmac_state->ctx.hmac_ctx = malloc(sizeof(*(evp_hmac_state->ctx.hmac_ctx))); } else { evp_hmac_state->ctx.evp_pkey = malloc(sizeof(*(evp_hmac_state->ctx.evp_pkey))); } } struct s2n_evp_hmac_state *cbmc_allocate_s2n_evp_hmac_state() { struct s2n_evp_hmac_state *evp_hmac_state = malloc(sizeof(*evp_hmac_state)); cbmc_populate_s2n_evp_hmac_state(evp_hmac_state); return evp_hmac_state; } void cbmc_populate_s2n_hash_state(struct s2n_hash_state* state) { CBMC_ENSURE_REF(state); /* `state->hash_impl` is never allocated. * It is always initialized based on the hashing algorithm. * If required, this initialization should be done in the validation function. */ cbmc_populate_s2n_evp_digest(&state->digest.high_level.evp); cbmc_populate_s2n_evp_digest(&state->digest.high_level.evp_md5_secondary); } struct s2n_hash_state* cbmc_allocate_s2n_hash_state() { struct s2n_hash_state *state = malloc(sizeof(*state)); cbmc_populate_s2n_hash_state(state); return state; } void cbmc_populate_s2n_hmac_state(struct s2n_hmac_state *state) { CBMC_ENSURE_REF(state); cbmc_populate_s2n_hash_state(&state->inner); cbmc_populate_s2n_hash_state(&state->inner_just_key); cbmc_populate_s2n_hash_state(&state->outer); cbmc_populate_s2n_hash_state(&state->outer_just_key); } struct s2n_hmac_state* cbmc_allocate_s2n_hmac_state() { struct s2n_hmac_state *state = malloc(sizeof(*state)); cbmc_populate_s2n_hmac_state(state); return state; } void cbmc_populate_s2n_hmac_evp_backup(struct s2n_hmac_evp_backup *backup) { CBMC_ENSURE_REF(backup); cbmc_populate_s2n_evp_digest(&backup->inner.evp); cbmc_populate_s2n_evp_digest(&backup->inner.evp_md5_secondary); cbmc_populate_s2n_evp_digest(&backup->inner_just_key.evp); cbmc_populate_s2n_evp_digest(&backup->inner_just_key.evp_md5_secondary); cbmc_populate_s2n_evp_digest(&backup->outer.evp); cbmc_populate_s2n_evp_digest(&backup->outer.evp_md5_secondary); cbmc_populate_s2n_evp_digest(&backup->outer_just_key.evp); cbmc_populate_s2n_evp_digest(&backup->outer_just_key.evp_md5_secondary); } struct s2n_hmac_evp_backup* cbmc_allocate_s2n_hmac_evp_backup() { struct s2n_hmac_evp_backup *backup = malloc(sizeof(*backup)); cbmc_populate_s2n_hmac_evp_backup(backup); return backup; } void cbmc_populate_s2n_map(struct s2n_map *s2n_map) { CBMC_ENSURE_REF(s2n_map); s2n_map->table = malloc(sizeof(*(s2n_map->table))); if (s2n_map->table != NULL) { cbmc_populate_s2n_blob(&(s2n_map->table->key)); cbmc_populate_s2n_blob(&(s2n_map->table->value)); } } struct s2n_map *cbmc_allocate_s2n_map() { struct s2n_map *s2n_map = malloc(sizeof(*s2n_map)); cbmc_populate_s2n_map(s2n_map); return s2n_map; } struct s2n_cipher_preferences *cbmc_allocate_s2n_cipher_preferences() { struct s2n_cipher_preferences *s2n_cipher_preferences = malloc(sizeof(*s2n_cipher_preferences)); return s2n_cipher_preferences; } struct s2n_kem_preferences *cbmc_allocate_s2n_kem_preferences() { struct s2n_kem_preferences *s2n_kem_preferences = malloc(sizeof(*s2n_kem_preferences)); return s2n_kem_preferences; } struct s2n_signature_preferences *cbmc_allocate_s2n_signature_preferences() { struct s2n_signature_preferences *s2n_signature_preferences = malloc(sizeof(*s2n_signature_preferences)); return s2n_signature_preferences; } struct s2n_ecc_preferences *cbmc_allocate_s2n_ecc_preferences() { struct s2n_ecc_preferences *s2n_ecc_preferences = malloc(sizeof(*s2n_ecc_preferences)); return s2n_ecc_preferences; } struct s2n_security_policy *cbmc_allocate_s2n_security_policy() { struct s2n_security_policy *s2n_security_policy = malloc(sizeof(*s2n_security_policy)); PTR_ENSURE_REF(s2n_security_policy); s2n_security_policy->cipher_preferences = cbmc_allocate_s2n_cipher_preferences(); s2n_security_policy->kem_preferences = cbmc_allocate_s2n_kem_preferences(); s2n_security_policy->signature_preferences = cbmc_allocate_s2n_signature_preferences(); s2n_security_policy->certificate_signature_preferences = cbmc_allocate_s2n_signature_preferences(); s2n_security_policy->ecc_preferences = cbmc_allocate_s2n_ecc_preferences(); return s2n_security_policy; } X509_STORE *cbmc_allocate_X509_STORE() { X509_STORE *x509_store = malloc(sizeof(*x509_store)); return x509_store; } void cbmc_populate_s2n_x509_trust_store(struct s2n_x509_trust_store *s2n_x509_trust_store) { CBMC_ENSURE_REF(s2n_x509_trust_store); s2n_x509_trust_store->trust_store = cbmc_allocate_X509_STORE(); } struct s2n_config *cbmc_allocate_s2n_config() { struct s2n_config *s2n_config = malloc(sizeof(*s2n_config)); PTR_ENSURE_REF(s2n_config); s2n_config->dhparams = cbmc_allocate_dh_params(); s2n_config->domain_name_to_cert_map = cbmc_allocate_s2n_map(); /* `s2n_config->default_certs_by_type` is never allocated. * If required, this initialization should be done in the proof harness. */ cbmc_populate_s2n_blob(&s2n_config->application_protocols); s2n_config->security_policy = cbmc_allocate_s2n_security_policy(); s2n_config->sys_clock_ctx = malloc(sizeof(*(s2n_config->sys_clock_ctx))); s2n_config->monotonic_clock_ctx = malloc(sizeof(*(s2n_config->monotonic_clock_ctx))); s2n_config->client_hello_cb = malloc(sizeof(*(s2n_config->client_hello_cb))); /* Function pointer. */ s2n_config->client_hello_cb_ctx = malloc(sizeof(*(s2n_config->client_hello_cb_ctx))); s2n_config->ticket_keys = cbmc_allocate_s2n_set(); s2n_config->ticket_key_hashes = cbmc_allocate_s2n_set(); s2n_config->cache_store_data = malloc(sizeof(*(s2n_config->cache_store_data))); s2n_config->cache_retrieve_data = malloc(sizeof(*(s2n_config->cache_retrieve_data))); s2n_config->cache_delete_data = malloc(sizeof(*(s2n_config->cache_delete_data))); s2n_config->data_for_verify_host = malloc(sizeof(*(s2n_config->data_for_verify_host))); cbmc_populate_s2n_x509_trust_store(&s2n_config->trust_store); s2n_config->psk_selection_ctx = malloc(sizeof(*(s2n_config->psk_selection_ctx))); s2n_config->key_log_ctx = malloc(sizeof(*(s2n_config->key_log_ctx))); s2n_config->session_ticket_ctx = malloc(sizeof(*(s2n_config->session_ticket_ctx))); return s2n_config; } void cbmc_populate_s2n_rsa_key(struct s2n_rsa_key *s2n_rsa_key) { CBMC_ENSURE_REF(s2n_rsa_key); s2n_rsa_key->rsa = malloc(sizeof(*(s2n_rsa_key->rsa))); } void cbmc_populate_s2n_ecdsa_key(struct s2n_ecdsa_key *s2n_ecdsa_key) { CBMC_ENSURE_REF(s2n_ecdsa_key); s2n_ecdsa_key->ec_key = malloc(sizeof(*(s2n_ecdsa_key->ec_key))); } void cbmc_populate_s2n_pkey(struct s2n_pkey *s2n_pkey) { CBMC_ENSURE_REF(s2n_pkey); cbmc_populate_s2n_rsa_key(&(s2n_pkey->key.rsa_key)); cbmc_populate_s2n_ecdsa_key(&(s2n_pkey->key.ecdsa_key)); /* `s2n_pkey->pkey` * `s2n_pkey->size` * `s2n_pkey->sign` * `s2n_pkey->verify` * `s2n_pkey->encrypt` * `s2n_pkey->decrypt` * `s2n_pkey->match` * `s2n_pkey->free` * `s2n_pkey->check_key` are never allocated. * If required, these initializations should be done in the proof harness. */ } struct s2n_pkey *cbmc_allocate_s2n_pkey() { struct s2n_pkey *s2n_pkey = malloc(sizeof(*s2n_pkey)); cbmc_populate_s2n_pkey(s2n_pkey); return s2n_pkey; } void cbmc_populate_s2n_ecc_evp_params(struct s2n_ecc_evp_params *s2n_ecc_evp_params) { CBMC_ENSURE_REF(s2n_ecc_evp_params); /* `s2n_ecc_evp_params->negotiated_curve` is never allocated. * If required, this initialization should be done in the proof harness. */ s2n_ecc_evp_params->evp_pkey = malloc(sizeof(*(s2n_ecc_evp_params->evp_pkey))); } struct s2n_ecc_named_curve *cbmc_allocate_s2n_ecc_named_curve() { struct s2n_ecc_named_curve *s2n_ecc_named_curve = malloc(sizeof(*s2n_ecc_named_curve)); /* `s2n_ecc_named_curve->name` * `s2n_ecc_named_curve->generate_key` are never allocated. * If required, these initializations should be done in the proof harness. */ return s2n_ecc_named_curve; } struct s2n_kem *cbmc_allocate_s2n_kem() { struct s2n_kem *s2n_kem = malloc(sizeof(*s2n_kem)); /* `s2n_kem->name` * `s2n_kem->generate_keypair` * `s2n_kem->encapsulate` * `s2n_kem->decapsulate` are never allocated. * If required, these initializations should be done in the proof harness. */ } struct s2n_kem_group *cbmc_allocate_s2n_kem_group() { struct s2n_kem_group *s2n_kem_group = malloc(sizeof(*s2n_kem_group)); PTR_ENSURE_REF(s2n_kem_group); /* `s2n_kem_group->name` is never allocated. * If required, this initialization should be done in the proof harness. */ s2n_kem_group->curve = cbmc_allocate_s2n_ecc_named_curve(); s2n_kem_group->kem = cbmc_allocate_s2n_kem(); return s2n_kem_group; } void cbmc_populate_s2n_kem_params(struct s2n_kem_params *s2n_kem_params) { CBMC_ENSURE_REF(s2n_kem_params); s2n_kem_params->kem = cbmc_allocate_s2n_kem(); cbmc_populate_s2n_blob(&(s2n_kem_params->public_key)); cbmc_populate_s2n_blob(&(s2n_kem_params->private_key)); cbmc_populate_s2n_blob(&(s2n_kem_params->shared_secret)); } void cbmc_populate_s2n_kem_group_params(struct s2n_kem_group_params *s2n_kem_group_params) { CBMC_ENSURE_REF(s2n_kem_group_params); s2n_kem_group_params->kem_group = cbmc_allocate_s2n_kem_group(); cbmc_populate_s2n_kem_params(&(s2n_kem_group_params->kem_params)); cbmc_populate_s2n_ecc_evp_params(&(s2n_kem_group_params->ecc_params)); } struct s2n_kem_group_params *cbmc_allocate_s2n_kem_group_params() { struct s2n_kem_group_params *s2n_kem_group_params = malloc(sizeof(*s2n_kem_group_params)); cbmc_populate_s2n_kem_group_params(s2n_kem_group_params); return s2n_kem_group_params; } void cbmc_populate_s2n_signature_scheme(struct s2n_signature_scheme *s2n_signature_scheme) { CBMC_ENSURE_REF(s2n_signature_scheme); s2n_signature_scheme->signature_curve = cbmc_allocate_s2n_ecc_named_curve(); } struct s2n_kex *cbmc_allocate_s2n_kex() { struct s2n_kex *s2n_kex = malloc(sizeof(*s2n_kex)); /* `s2n_kex->hybrid` * `s2n_kex->connection_supported` * `s2n_kex->configure_connection` * `s2n_kex->server_key_recv_read_data` * `s2n_kex->server_key_recv_parse_data` * `s2n_kex->server_key_send` * `s2n_kex->client_key_recv` * `s2n_kex->client_key_send` * `s2n_kex->prf` are never allocated. * If required, these initializations should be done in the proof harness. */ return s2n_kex; } struct s2n_cipher *cbmc_allocate_s2n_cipher() { struct s2n_cipher *s2n_cipher = malloc(sizeof(*s2n_cipher)); /* `s2n_cipher->io.stream` * `s2n_cipher->io.aead` * `s2n_cipher->io.cbc` * `s2n_cipher->io.comp` * `s2n_cipher->is_available` * `s2n_cipher->init` * `s2n_cipher->set_decryption_key` * `s2n_cipher->set_encryption_key` * `s2n_cipher->destroy_key` are never allocated. * If required, these initializations should be done in the proof harness. */ return s2n_cipher; } struct s2n_record_algorithm *cbmc_allocate_s2n_record_algorithm() { struct s2n_record_algorithm *s2n_record_algorithm = malloc(sizeof(*s2n_record_algorithm)); PTR_ENSURE_REF(s2n_record_algorithm); s2n_record_algorithm->cipher = cbmc_allocate_s2n_cipher(); return s2n_record_algorithm; } struct s2n_cipher_suite *cbmc_allocate_s2n_cipher_suite() { struct s2n_cipher_suite *s2n_cipher_suite = malloc(sizeof(*s2n_cipher_suite)); PTR_ENSURE_REF(s2n_cipher_suite); /* `s2n_cipher_suite->name` * `s2n_cipher_suite->all_record_algs` * `s2n_cipher_suite->sslv3_cipher_suite` are never allocated. * If required, these initializations should be done in the proof harness. */ s2n_cipher_suite->key_exchange_alg = cbmc_allocate_s2n_kex(); s2n_cipher_suite->record_alg = cbmc_allocate_s2n_record_algorithm(); s2n_cipher_suite->sslv3_record_alg = cbmc_allocate_s2n_record_algorithm(); return s2n_cipher_suite; } void cbmc_populate_s2n_session_key(struct s2n_session_key *s2n_session_key) { CBMC_ENSURE_REF(s2n_session_key); s2n_session_key->evp_cipher_ctx = malloc(sizeof(*(s2n_session_key->evp_cipher_ctx))); } void cbmc_populate_s2n_kex_parameters(struct s2n_kex_parameters *s2n_kex_parameters) { cbmc_populate_s2n_dh_params(&(s2n_kex_parameters->server_dh_params)); cbmc_populate_s2n_ecc_evp_params(&(s2n_kex_parameters->server_ecc_evp_params)); /* `s2n_crypto_parameters->mutually_supported_curves` * `s2n_crypto_parameters->client_ecc_evp_params` * `s2n_crypto_parameters->client_kem_group_params` * `s2n_crypto_parameters->mutually_supported_kem_groups` are never allocated. * If required, these initializations should be done in the proof harness. */ cbmc_populate_s2n_kem_group_params(&(s2n_kex_parameters->server_kem_group_params)); cbmc_populate_s2n_kem_params(&(s2n_kex_parameters->kem_params)); cbmc_populate_s2n_blob(&(s2n_kex_parameters->client_key_exchange_message)); cbmc_populate_s2n_blob(&(s2n_kex_parameters->client_pq_kem_extension)); } void cbmc_populate_s2n_crypto_parameters(struct s2n_crypto_parameters *s2n_crypto_parameters) { CBMC_ENSURE_REF(s2n_crypto_parameters); s2n_crypto_parameters->cipher_suite = cbmc_allocate_s2n_cipher_suite(); cbmc_populate_s2n_session_key(&(s2n_crypto_parameters->client_key)); cbmc_populate_s2n_session_key(&(s2n_crypto_parameters->server_key)); cbmc_populate_s2n_hmac_state(&(s2n_crypto_parameters->client_record_mac)); cbmc_populate_s2n_hmac_state(&(s2n_crypto_parameters->server_record_mac)); } struct s2n_crypto_parameters *cbmc_allocate_s2n_crypto_parameters() { struct s2n_crypto_parameters *s2n_crypto_parameters = malloc(sizeof(*s2n_crypto_parameters)); cbmc_populate_s2n_crypto_parameters(s2n_crypto_parameters); return s2n_crypto_parameters; } void cbmc_populate_s2n_cert(struct s2n_cert *s2n_cert) { CBMC_ENSURE_REF(s2n_cert); cbmc_populate_s2n_blob(&(s2n_cert->raw)); /* `s2n_cert->next` is never allocated. * If required, this initialization should be done in the proof harness. */ } struct s2n_cert *cbmc_allocate_s2n_cert() { struct s2n_cert *s2n_cert = malloc(sizeof(*s2n_cert)); cbmc_populate_s2n_cert(s2n_cert); return s2n_cert; } void cbmc_populate_s2n_cert_chain(struct s2n_cert_chain *s2n_cert_chain) { CBMC_ENSURE_REF(s2n_cert_chain); s2n_cert_chain->head = cbmc_allocate_s2n_cert(); } struct s2n_cert_chain *cbmc_allocate_s2n_cert_chain() { struct s2n_cert_chain *s2n_cert_chain = malloc(sizeof(*s2n_cert_chain)); cbmc_populate_s2n_cert_chain(s2n_cert_chain); return s2n_cert_chain; } void cbmc_populate_s2n_cert_chain_and_key(struct s2n_cert_chain_and_key *s2n_cert_chain_and_key) { CBMC_ENSURE_REF(s2n_cert_chain_and_key); s2n_cert_chain_and_key->cert_chain = cbmc_allocate_s2n_cert_chain(); s2n_cert_chain_and_key->private_key = cbmc_allocate_s2n_pkey(); cbmc_populate_s2n_blob(&(s2n_cert_chain_and_key->ocsp_status)); cbmc_populate_s2n_blob(&(s2n_cert_chain_and_key->sct_list)); s2n_cert_chain_and_key->san_names = cbmc_allocate_s2n_array(); s2n_cert_chain_and_key->cn_names = cbmc_allocate_s2n_array(); s2n_cert_chain_and_key->context = malloc(sizeof(*(s2n_cert_chain_and_key->context))); } void cbmc_populate_s2n_handshake_parameters(struct s2n_handshake_parameters *s2n_handshake_parameters) { CBMC_ENSURE_REF(s2n_handshake_parameters); cbmc_populate_s2n_pkey(&(s2n_handshake_parameters->server_public_key)); cbmc_populate_s2n_pkey(&(s2n_handshake_parameters->client_public_key)); cbmc_populate_s2n_signature_scheme(&(s2n_handshake_parameters->conn_sig_scheme)); cbmc_populate_s2n_blob(&(s2n_handshake_parameters->client_cert_chain)); cbmc_populate_s2n_signature_scheme(&(s2n_handshake_parameters->client_cert_sig_scheme)); cbmc_populate_s2n_cert_chain_and_key(s2n_handshake_parameters->our_chain_and_key); /* `s2n_handshake_parameters->exact_sni_matches` * `s2n_handshake_parameters->wc_sni_matches` are never allocated. * If required, these initializations should be done in the proof harness. */ } void cbmc_populate_s2n_early_data_config(struct s2n_early_data_config *s2n_early_data_config) { CBMC_ENSURE_REF(s2n_early_data_config); s2n_early_data_config->cipher_suite = cbmc_allocate_s2n_cipher_suite(); cbmc_populate_s2n_blob(&(s2n_early_data_config->application_protocol)); cbmc_populate_s2n_blob(&(s2n_early_data_config->context)); } void cbmc_populate_s2n_psk(struct s2n_psk *s2n_psk) { CBMC_ENSURE_REF(s2n_psk); cbmc_populate_s2n_blob(&(s2n_psk->identity)); cbmc_populate_s2n_blob(&(s2n_psk->secret)); cbmc_populate_s2n_blob(&(s2n_psk->early_secret)); cbmc_populate_s2n_early_data_config(&(s2n_psk->early_data_config)); } struct s2n_psk *cbmc_allocate_s2n_psk() { struct s2n_psk *s2n_psk = malloc(sizeof(*s2n_psk)); cbmc_populate_s2n_psk(s2n_psk); return s2n_psk; } void cbmc_populate_s2n_psk_parameters(struct s2n_psk_parameters *s2n_psk_parameters) { CBMC_ENSURE_REF(s2n_psk_parameters); cbmc_populate_s2n_blob(&(s2n_psk_parameters->psk_list.mem)); s2n_psk_parameters->chosen_psk = cbmc_allocate_s2n_psk(); } void cbmc_populate_s2n_prf_working_space(struct s2n_prf_working_space *s2n_prf_working_space) { CBMC_ENSURE_REF(s2n_prf_working_space); /* `s2n_prf_working_space->tls.p_hash_hmac_impl` is never allocated. * It is always initialized based on the hashing algorithm. * If required, this initialization should be done in the validation function. */ cbmc_populate_s2n_hmac_state(&(s2n_prf_working_space->p_hash.s2n_hmac)); cbmc_populate_s2n_evp_hmac_state(&(s2n_prf_working_space->p_hash.evp_hmac)); } struct s2n_prf_working_space* cbmc_allocate_s2n_prf_working_space() { struct s2n_prf_working_space *workspace = malloc(sizeof(*workspace)); cbmc_populate_s2n_prf_working_space(workspace); return workspace; } void cbmc_populate_s2n_handshake(struct s2n_handshake *s2n_handshake) { CBMC_ENSURE_REF(s2n_handshake); cbmc_populate_s2n_stuffer(&(s2n_handshake->io)); cbmc_populate_s2n_hash_state(&(s2n_handshake->hashes->md5)); cbmc_populate_s2n_hash_state(&(s2n_handshake->hashes->sha1)); cbmc_populate_s2n_hash_state(&(s2n_handshake->hashes->sha224)); cbmc_populate_s2n_hash_state(&(s2n_handshake->hashes->sha256)); cbmc_populate_s2n_hash_state(&(s2n_handshake->hashes->sha384)); cbmc_populate_s2n_hash_state(&(s2n_handshake->hashes->sha512)); cbmc_populate_s2n_hash_state(&(s2n_handshake->hashes->md5_sha1)); cbmc_populate_s2n_hash_state(&(s2n_handshake->hashes->hash_workspace)); /* `s2n_handshake->early_data_async_state.conn` is never allocated. * If required, this initialization should be done in the validation function. */ } void cbmc_populate_s2n_client_hello(struct s2n_client_hello *s2n_client_hello) { CBMC_ENSURE_REF(s2n_client_hello); cbmc_populate_s2n_blob(&(s2n_client_hello->raw_message)); cbmc_populate_s2n_blob(&(s2n_client_hello->cipher_suites)); } void cbmc_populate_s2n_x509_validator(struct s2n_x509_validator *s2n_x509_validator) { CBMC_ENSURE_REF(s2n_x509_validator); s2n_x509_validator->trust_store = malloc(sizeof(*(s2n_x509_validator->trust_store))); if (s2n_x509_validator->trust_store != NULL) { s2n_x509_validator->trust_store->trust_store = malloc(sizeof(*(s2n_x509_validator->trust_store->trust_store))); } s2n_x509_validator->store_ctx = malloc(sizeof(*(s2n_x509_validator->store_ctx))); s2n_x509_validator->cert_chain_from_wire = malloc(sizeof(*(s2n_x509_validator->cert_chain_from_wire))); } void cbmc_populate_s2n_ticket_fields(struct s2n_ticket_fields *s2n_ticket_fields) { CBMC_ENSURE_REF(s2n_ticket_fields); cbmc_populate_s2n_blob(&(s2n_ticket_fields->session_secret)); } void cbmc_populate_s2n_connection(struct s2n_connection *s2n_connection) { CBMC_ENSURE_REF(s2n_connection); s2n_connection->config = cbmc_allocate_s2n_config(); s2n_connection->security_policy_override = cbmc_allocate_s2n_security_policy(); s2n_connection->context = malloc(sizeof(*(s2n_connection->context))); s2n_connection->secret_cb = malloc(sizeof(*(s2n_connection->secret_cb))); /* Function pointer. */ s2n_connection->secret_cb_context = malloc(sizeof(*(s2n_connection->secret_cb_context))); s2n_connection->send = malloc(sizeof(*(s2n_connection->send))); /* Function pointer. */ s2n_connection->recv = malloc(sizeof(*(s2n_connection->recv))); /* Function pointer. */ s2n_connection->send_io_context = malloc(sizeof(*(s2n_connection->secret_cb))); s2n_connection->recv_io_context = malloc(sizeof(*(s2n_connection->secret_cb))); cbmc_populate_s2n_crypto_parameters(s2n_connection->initial); cbmc_populate_s2n_crypto_parameters(s2n_connection->secure); cbmc_populate_s2n_kex_parameters(&(s2n_connection->kex_params)); s2n_connection->client = cbmc_allocate_s2n_crypto_parameters(); s2n_connection->server = cbmc_allocate_s2n_crypto_parameters(); cbmc_populate_s2n_handshake_parameters(&(s2n_connection->handshake_params)); cbmc_populate_s2n_psk_parameters(&(s2n_connection->psk_params)); s2n_connection->prf_space = cbmc_allocate_s2n_prf_working_space(); cbmc_populate_s2n_stuffer(&(s2n_connection->header_in)); cbmc_populate_s2n_stuffer(&(s2n_connection->in)); cbmc_populate_s2n_stuffer(&(s2n_connection->out)); cbmc_populate_s2n_stuffer(&(s2n_connection->alert_in)); cbmc_populate_s2n_handshake(&(s2n_connection->handshake)); cbmc_populate_s2n_blob(&(s2n_connection->status_response)); cbmc_populate_s2n_blob(&(s2n_connection->ct_response)); cbmc_populate_s2n_blob(&(s2n_connection->our_quic_transport_parameters)); cbmc_populate_s2n_blob(&(s2n_connection->peer_quic_transport_parameters)); cbmc_populate_s2n_client_hello(&(s2n_connection->client_hello)); cbmc_populate_s2n_x509_validator(&(s2n_connection->x509_validator)); s2n_connection->verify_host_fn = malloc(sizeof(*(s2n_connection->verify_host_fn))); /* Function pointer. */ s2n_connection->data_for_verify_host = malloc(sizeof(*(s2n_connection->data_for_verify_host))); cbmc_populate_s2n_blob(&(s2n_connection->client_ticket)); cbmc_populate_s2n_ticket_fields(&(s2n_connection->tls13_ticket_fields)); cbmc_populate_s2n_stuffer(&(s2n_connection->client_ticket_to_decrypt)); cbmc_populate_s2n_blob(&(s2n_connection->application_protocols_overridden)); cbmc_populate_s2n_blob(&(s2n_connection->cookie)); cbmc_populate_s2n_blob(&(s2n_connection->server_early_data_context)); } struct s2n_connection *cbmc_allocate_s2n_connection() { struct s2n_connection *s2n_connection = malloc(sizeof(*s2n_connection)); cbmc_populate_s2n_connection(s2n_connection); return s2n_connection; } struct s2n_socket_read_io_context *cbmc_allocate_s2n_socket_read_io_context() { struct s2n_socket_read_io_context *s2n_socket_read_io_context = malloc(sizeof(*s2n_socket_read_io_context)); return s2n_socket_read_io_context; } struct s2n_socket_write_io_context *cbmc_allocate_s2n_socket_write_io_context() { struct s2n_socket_write_io_context *s2n_socket_write_io_context = malloc(sizeof(*s2n_socket_write_io_context)); return s2n_socket_write_io_context; }