Ejemplo n.º 1
0
int s2n_asn1der_to_rsa_public_key(struct s2n_rsa_public_key *key, struct s2n_blob *asn1der)
{
    uint8_t *original_ptr = asn1der->data;
    X509 *cert = d2i_X509(NULL, (const unsigned char **)(void *)&asn1der->data, asn1der->size);
    if (cert == NULL) {
        S2N_ERROR(S2N_ERR_DECODE_CERTIFICATE);
    }
    if (asn1der->data - original_ptr != asn1der->size) {
        X509_free(cert);
        S2N_ERROR(S2N_ERR_DECODE_CERTIFICATE);
    }
    asn1der->data = original_ptr;

    EVP_PKEY *public_key = X509_get_pubkey(cert);
    X509_free(cert);

    if (public_key == NULL) {
        S2N_ERROR(S2N_ERR_DECODE_CERTIFICATE);
    }

    if (public_key->type != EVP_PKEY_RSA) {
        EVP_PKEY_free(public_key);
        S2N_ERROR(S2N_ERR_DECODE_CERTIFICATE);
    }

    key->rsa = EVP_PKEY_get1_RSA(public_key);
    if (key->rsa == NULL) {
        EVP_PKEY_free(public_key);
        S2N_ERROR(S2N_ERR_DECODE_CERTIFICATE);
    }

    EVP_PKEY_free(public_key);

    return 0;
}
Ejemplo n.º 2
0
static int s2n_set_p_g_Ys_dh_params(struct s2n_dh_params *dh_params, struct s2n_blob *p, struct s2n_blob *g, struct s2n_blob *Ys)
{
    BIGNUM *bn_p = BN_bin2bn((const unsigned char *)p->data, p->size, NULL);
    BIGNUM *bn_g = BN_bin2bn((const unsigned char *)g->data, g->size, NULL);
    BIGNUM *bn_Ys = BN_bin2bn((const unsigned char *)Ys->data, Ys->size, NULL);

    #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined LIBRESSL_VERSION_NUMBER
        dh_params->dh->p = bn_p;
        dh_params->dh->g = bn_g;
        dh_params->dh->pub_key = bn_Ys;
    #else
        if (DH_set0_pqg(dh_params->dh, bn_p, NULL, bn_g) == 0) {
            /* Per https://www.openssl.org/docs/man1.1.0/crypto/DH_get0_pqg.html:
             * values that have been passed in should not be freed directly after this function has been called
             */
            S2N_ERROR(S2N_ERR_DH_PARAMS_CREATE);
        }

        if (DH_set0_key(dh_params->dh, bn_Ys, NULL) == 0) {
            /* Same as DH_set0_pqg */
            S2N_ERROR(S2N_ERR_DH_PARAMS_CREATE);
        }
    #endif

    return 0;
}
Ejemplo n.º 3
0
static int s2n_check_p_g_dh_params(struct s2n_dh_params *dh_params)
{
    notnull_check(dh_params);
    notnull_check(dh_params->dh);

    const BIGNUM *p = s2n_get_p_dh_param(dh_params);
    const BIGNUM *g = s2n_get_g_dh_param(dh_params);

    notnull_check(g);
    notnull_check(p);

    if (DH_size(dh_params->dh) < S2N_MIN_DH_PRIME_SIZE_BYTES) {
        S2N_ERROR(S2N_ERR_DH_PARAMS_CREATE);
    }

    if (BN_is_zero(g)) {
        S2N_ERROR(S2N_ERR_DH_PARAMS_CREATE);
    }

    if (BN_is_zero(p)) {
        S2N_ERROR(S2N_ERR_DH_PARAMS_CREATE);
    }

    return 0;
}
Ejemplo n.º 4
0
int s2n_process_alert_fragment(struct s2n_connection *conn)
{
    if (s2n_stuffer_data_available(&conn->alert_in) == 2) {
        S2N_ERROR(S2N_ERR_ALERT_PRESENT);
    }

    while (s2n_stuffer_data_available(&conn->in)) {
        uint8_t bytes_required = 2;

        /* Alerts are two bytes long, but can still be fragmented or coalesced */
        if (s2n_stuffer_data_available(&conn->alert_in) == 1) {
            bytes_required = 1;
        }

        int bytes_to_read = MIN(bytes_required, s2n_stuffer_data_available(&conn->in));

        GUARD(s2n_stuffer_copy(&conn->in, &conn->alert_in, bytes_to_read));

        if (s2n_stuffer_data_available(&conn->alert_in) == 2) {
            conn->closed = 1;

            /* Close notifications are handled as shutdowns */
            if (conn->alert_in_data[1] == S2N_TLS_ALERT_CLOSE_NOTIFY) {
                return 0;
            }

            /* All other alerts are treated as fatal errors (even warnings) */
            S2N_ERROR(S2N_ERR_ALERT);
        }
    }

    return 0;
}
Ejemplo n.º 5
0
int s2n_rsa_sign(struct s2n_rsa_private_key *key, struct s2n_hash_state *digest, struct s2n_blob *signature)
{
    uint8_t digest_out[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH];

    int type, digest_length;
    if (digest->alg == S2N_HASH_MD5_SHA1) {
        type = NID_md5_sha1;
        digest_length = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH;
    } else if (digest->alg == S2N_HASH_SHA1) {
        type = NID_sha1;
        digest_length = SHA_DIGEST_LENGTH;
    } else {
        S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
    }

    GUARD(s2n_hash_digest(digest, digest_out, digest_length));

    unsigned int signature_size = signature->size;
    if (RSA_sign(type, digest_out, digest_length, signature->data, &signature_size, key->rsa) == 0) {
        S2N_ERROR(S2N_ERR_SIGN);
    }
    if (signature_size > signature->size) {
        S2N_ERROR(S2N_ERR_SIZE_MISMATCH);
    }
    signature->size = signature_size;

    return 0;
}
Ejemplo n.º 6
0
int s2n_map_add(struct s2n_map *map, struct s2n_blob *key, struct s2n_blob *value)
{
    if (map->immutable) {
        S2N_ERROR(S2N_ERR_MAP_IMMUTABLE);
    }

    if (map->capacity < (map->size * 2)) {
        /* Embiggen the map */
        GUARD(s2n_map_embiggen(map, map->capacity * 2));
    }

    uint32_t slot = s2n_map_slot(map, key);

    /* Linear probing until we find an empty slot */
    while(map->table[slot].key.size) {
        if (key->size != map->table[slot].key.size ||
            memcmp(key->data,  map->table[slot].key.data, key->size)) {
            slot++;
            slot %= map->capacity;
            continue;
        }

        /* We found a duplicate key */
        S2N_ERROR(S2N_ERR_MAP_DUPLICATE);
    }

    GUARD(s2n_dup(key, &map->table[slot].key));
    GUARD(s2n_dup(value, &map->table[slot].value));
    map->size++;

    return 0;
}
Ejemplo n.º 7
0
/* See http://www-archive.mozilla.org/projects/security/pki/nss/ssl/draft02.html 2.5 */
int s2n_sslv2_client_hello_recv(struct s2n_connection *conn)
{
    struct s2n_stuffer *in = &conn->handshake.io;
    uint16_t session_id_length;
    uint16_t cipher_suites_length;
    uint16_t challenge_length;
    uint8_t *cipher_suites;

    if (conn->client_protocol_version < conn->config->cipher_preferences->minimum_protocol_version || conn->client_protocol_version > conn->server_protocol_version) {
        GUARD(s2n_queue_reader_unsupported_protocol_version_alert(conn));
        S2N_ERROR(S2N_ERR_BAD_MESSAGE);
    }
    conn->actual_protocol_version = MIN(conn->client_protocol_version, conn->server_protocol_version);
    conn->client_hello_version = S2N_SSLv2;

    /* We start 5 bytes into the record */
    GUARD(s2n_stuffer_read_uint16(in, &cipher_suites_length));

    if (cipher_suites_length % S2N_SSLv2_CIPHER_SUITE_LEN) {
        S2N_ERROR(S2N_ERR_BAD_MESSAGE);
    }

    GUARD(s2n_stuffer_read_uint16(in, &session_id_length));

    GUARD(s2n_stuffer_read_uint16(in, &challenge_length));

    if (challenge_length > S2N_TLS_RANDOM_DATA_LEN) {
        S2N_ERROR(S2N_ERR_BAD_MESSAGE);
    }

    cipher_suites = s2n_stuffer_raw_read(in, cipher_suites_length);
    notnull_check(cipher_suites);
    GUARD(s2n_set_cipher_as_sslv2_server(conn, cipher_suites, cipher_suites_length / S2N_SSLv2_CIPHER_SUITE_LEN));

    if (session_id_length > s2n_stuffer_data_available(in)) {
        S2N_ERROR(S2N_ERR_BAD_MESSAGE);
    }
    if (session_id_length > 0 && session_id_length <= S2N_TLS_SESSION_ID_MAX_LEN) {
        GUARD(s2n_stuffer_read_bytes(in, conn->session_id, session_id_length));
        conn->session_id_len = (uint8_t) session_id_length;
    } else {
        GUARD(s2n_stuffer_skip_read(in, session_id_length));
    }

    struct s2n_blob b;
    b.data = conn->secure.client_random;
    b.size = S2N_TLS_RANDOM_DATA_LEN;

    b.data += S2N_TLS_RANDOM_DATA_LEN - challenge_length;
    b.size -= S2N_TLS_RANDOM_DATA_LEN - challenge_length;

    GUARD(s2n_stuffer_read(in, &b));

    conn->server->chosen_cert_chain = conn->config->cert_and_key_pairs;
    GUARD(s2n_conn_set_handshake_type(conn));

    return 0;
}
Ejemplo n.º 8
0
static int s2n_set_cipher_as_server(struct s2n_connection *conn, uint8_t *wire, uint32_t count, uint32_t cipher_suite_len)
{
    uint8_t fallback_scsv[S2N_TLS_CIPHER_SUITE_LEN] = { TLS_FALLBACK_SCSV };
    struct s2n_cipher_suite *higher_vers_match = NULL;

    /* s2n supports only server order */
    for (int i = 0; i < conn->config->cipher_preferences->count; i++) {
        uint8_t *ours = conn->config->cipher_preferences->wire_format + (i * S2N_TLS_CIPHER_SUITE_LEN);
        for (int j = 0; j < count; j++) {
            uint8_t *theirs = wire + (j * cipher_suite_len) + (cipher_suite_len - S2N_TLS_CIPHER_SUITE_LEN);

            if (!memcmp(fallback_scsv, theirs, S2N_TLS_CIPHER_SUITE_LEN)) {
                if (conn->client_protocol_version < S2N_TLS12) {
                    conn->closed = 1;
                    S2N_ERROR(S2N_ERR_FALLBACK_DETECTED);
                }
            }

            if (!memcmp(ours, theirs, S2N_TLS_CIPHER_SUITE_LEN)) {
                /* We have a match */
                struct s2n_cipher_suite *match;

                match = s2n_cipher_suite_match(ours);
                /* This should never happen */
                if (match == NULL) {
                    S2N_ERROR(S2N_ERR_CIPHER_NOT_SUPPORTED);
                }

                /* Don't choose DHE key exchange if it's not configured. */
                if (conn->config->dhparams == NULL && match->key_exchange_alg == &s2n_dhe) {
                    continue;
                }
                /* Don't choose EC ciphers if the curve was not agreed upon. */
                if (conn->pending.server_ecc_params.negotiated_curve == NULL && (match->key_exchange_alg->flags & S2N_KEY_EXCHANGE_ECC)) {
                    continue;
                }

                /* Don't immediately choose a cipher the client shouldn't be able to support */
                if (conn->client_protocol_version < match->minimum_required_tls_version) {
                    higher_vers_match = match;
                    continue;
                }

                conn->pending.cipher_suite = match;
                return 0;
            }
        }
    }

    /* Settle for a cipher with a higher required proto version, if it was set */
    if (higher_vers_match != NULL) {
        conn->pending.cipher_suite = higher_vers_match;
        return 0;
    }

    S2N_ERROR(S2N_ERR_CIPHER_NOT_SUPPORTED);
}
Ejemplo n.º 9
0
Archivo: s2n_mem.c Proyecto: PKRoma/s2n
int s2n_realloc(struct s2n_blob *b, uint32_t size)
{
    if (size == 0) {
        return s2n_free(b);
    }

    /* blob already has space for the request */
    if (size < b->allocated) {
        b->size = size;
        return 0;
    }

    void *data;
    if (!use_mlock) {
        data = realloc(b->data, size);
        if (!data) {
            S2N_ERROR(S2N_ERR_ALLOC);
        }

        b->data = data;
        b->size = size;
        b->allocated = size;
        return 0;
    }

    /* Page aligned allocation required for mlock */
    uint32_t allocate = page_size * (((size - 1) / page_size) + 1);
    if (posix_memalign(&data, page_size, allocate)) {
        S2N_ERROR(S2N_ERR_ALLOC);
    }

    if (b->size) {
        memcpy_check(data, b->data, b->size);
        GUARD(s2n_free(b));
    }

    b->data = data;
    b->size = size;
    b->allocated = allocate;

#ifdef MADV_DONTDUMP
    if (madvise(b->data, size, MADV_DONTDUMP) < 0) {
        GUARD(s2n_free(b));
        S2N_ERROR(S2N_ERR_MADVISE);
    }
#endif

    if (mlock(b->data, size) < 0) {
        GUARD(s2n_free(b));
        S2N_ERROR(S2N_ERR_MLOCK);
    }
    b->mlocked = 1;

    return 0;
}
Ejemplo n.º 10
0
int s2n_rsa_encrypt(struct s2n_rsa_public_key *key, struct s2n_blob *in, struct s2n_blob *out)
{
    if (out->size < s2n_rsa_public_encrypted_size(key)) {
        S2N_ERROR(S2N_ERR_NOMEM);
    }

    int r = RSA_public_encrypt(in->size, (unsigned char *)in->data, (unsigned char *)out->data, key->rsa, RSA_PKCS1_PADDING);
    if (r != out->size) {
        S2N_ERROR(S2N_ERR_SIZE_MISMATCH);
    }

    return 0;
}
Ejemplo n.º 11
0
static int s2n_composite_cipher_aes_sha_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out)
{
    eq_check(out->size, in->size);

    if (EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data) == 0) {
        S2N_ERROR(S2N_ERR_KEY_INIT);
    }

    if (EVP_Cipher(key->evp_cipher_ctx, out->data, in->data, in->size) == 0) {
        S2N_ERROR(S2N_ERR_DECRYPT);
    }

    return 0;
}
Ejemplo n.º 12
0
int s2n_dh_params_check(struct s2n_dh_params *params)
{
    int codes = 0;

    if (DH_check(params->dh, &codes) == 0) {
        S2N_ERROR(S2N_ERR_DH_PARAMETER_CHECK);
    }

    if (codes != 0) {
        S2N_ERROR(S2N_ERR_DH_PARAMETER_CHECK);
    }

    return 0;
}
Ejemplo n.º 13
0
int s2n_asn1der_to_rsa_private_key(struct s2n_rsa_private_key *key, struct s2n_blob *asn1der)
{
    uint8_t *original_ptr = asn1der->data;

    key->rsa = d2i_RSAPrivateKey(NULL, (const unsigned char **)(void *)&asn1der->data, asn1der->size);
    if (key->rsa == NULL) {
        S2N_ERROR(S2N_ERR_DECODE_PRIVATE_KEY);
    }
    if (asn1der->data - original_ptr != asn1der->size) {
        S2N_ERROR(S2N_ERR_DECODE_PRIVATE_KEY);
    }

    return 0;
}
Ejemplo n.º 14
0
int s2n_set_server_name(struct s2n_connection *conn, const char *server_name)
{
    if (conn->mode != S2N_CLIENT) {
        S2N_ERROR(S2N_ERR_CLIENT_MODE);
    }

    int len = strlen(server_name);
    if (len > 255) {
        S2N_ERROR(S2N_ERR_SERVER_NAME_TOO_LONG);
    }

    memcpy_check(conn->server_name, server_name, len);

    return 0;
}
Ejemplo n.º 15
0
int s2n_cbc_cipher_3des_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out)
{
    gte_check(out->size, in->size);

    if (EVP_DecryptInit_ex(&key->native_format.evp_cipher_ctx, NULL, NULL, NULL, iv->data) == 0) {
        S2N_ERROR(S2N_ERR_KEY_INIT);
    }

    int len = out->size;
    if (EVP_DecryptUpdate(&key->native_format.evp_cipher_ctx, out->data, &len, in->data, in->size) == 0) {
        S2N_ERROR(S2N_ERR_DECRYPT);
    }

    return 0;
}
Ejemplo n.º 16
0
static int s2n_composite_cipher_aes_sha_initial_hmac(struct s2n_session_key *key, uint8_t *sequence_number, uint8_t content_type,
                                                     uint16_t protocol_version, uint16_t payload_and_eiv_len, int *extra)
{
    uint8_t ctrl_buf[S2N_TLS12_AAD_LEN];
    struct s2n_blob ctrl_blob = { .data = ctrl_buf, .size = S2N_TLS12_AAD_LEN };
    struct s2n_stuffer ctrl_stuffer;
    GUARD(s2n_stuffer_init(&ctrl_stuffer, &ctrl_blob));

    GUARD(s2n_stuffer_write_bytes(&ctrl_stuffer, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
    GUARD(s2n_stuffer_write_uint8(&ctrl_stuffer, content_type));
    GUARD(s2n_stuffer_write_uint8(&ctrl_stuffer, protocol_version / 10));
    GUARD(s2n_stuffer_write_uint8(&ctrl_stuffer, protocol_version % 10));
    GUARD(s2n_stuffer_write_uint16(&ctrl_stuffer, payload_and_eiv_len));

    /* This will unnecessarily mangle the input buffer, which is fine since it's temporary
     * Return value will be length of digest, padding, and padding length byte.
     * See https://github.com/openssl/openssl/blob/master/crypto/evp/e_aes_cbc_hmac_sha1.c#L814
     * and https://github.com/openssl/openssl/blob/4f0c475719defd7c051964ef9964cc6e5b3a63bf/ssl/record/ssl3_record.c#L743
     */
    int ctrl_ret = EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_TLS1_AAD, S2N_TLS12_AAD_LEN, ctrl_buf);

    if (ctrl_ret < 0) {
        S2N_ERROR(S2N_ERR_INITIAL_HMAC);
    }

    *extra = ctrl_ret;
    return 0;
}
Ejemplo n.º 17
0
int s2n_kem_find_supported_kem(struct s2n_blob *client_kem_ids, const struct s2n_kem *server_kem_pref_list,
                               const int num_server_supported_kems, const struct s2n_kem **matching_kem)
{
    struct s2n_stuffer client_kems_in = {{0}};

    GUARD(s2n_stuffer_init(&client_kems_in, client_kem_ids));
    GUARD(s2n_stuffer_write(&client_kems_in, client_kem_ids));

    for (int i = 0; i < num_server_supported_kems; i++) {
        const struct s2n_kem candidate_server_kem_name = server_kem_pref_list[i];
        for (int j = 0; j < client_kem_ids->size / 2; j++) {
            kem_extension_size candidate_client_kem_id;
            GUARD(s2n_stuffer_read_uint16(&client_kems_in, &candidate_client_kem_id));

            if (candidate_server_kem_name.kem_extension_id == candidate_client_kem_id) {
                *matching_kem = &server_kem_pref_list[i];
                return 0;
            }
        }
        GUARD(s2n_stuffer_reread(&client_kems_in));
    }

    /* Nothing found */
    S2N_ERROR(S2N_ERR_KEM_UNSUPPORTED_PARAMS);
    return 0;
}
Ejemplo n.º 18
0
int s2n_client_ccs_recv(struct s2n_connection *conn)
{
    uint8_t type;

    GUARD(s2n_prf_client_finished(conn));
    GUARD(s2n_prf_key_expansion(conn));

    struct s2n_blob seq = {.data = conn->pending.client_sequence_number, .size = sizeof(conn->pending.client_sequence_number) };
    GUARD(s2n_blob_zero(&seq));

    /* Update the client to use the pending cipher-suite */
    conn->client = &conn->pending;

    GUARD(s2n_stuffer_read_uint8(&conn->handshake.io, &type));
    if (type != CHANGE_CIPHER_SPEC_TYPE) {
        S2N_ERROR(S2N_ERR_BAD_MESSAGE);
    }

    /* Flush any partial alert messages that were pending */
    GUARD(s2n_stuffer_wipe(&conn->alert_in));

    return 0;
}

int s2n_client_ccs_send(struct s2n_connection *conn)
{
    GUARD(s2n_stuffer_write_uint8(&conn->handshake.io, CHANGE_CIPHER_SPEC_TYPE));

    return 0;
}
Ejemplo n.º 19
0
int s2n_handshake_get_hash_state(struct s2n_connection *conn, s2n_hash_algorithm hash_alg, struct s2n_hash_state *hash_state)
{
    switch (hash_alg) {
    case S2N_HASH_MD5:
        *hash_state = conn->handshake.md5;
        break;
    case S2N_HASH_SHA1:
        *hash_state = conn->handshake.sha1;
        break;
    case S2N_HASH_SHA224:
        *hash_state = conn->handshake.sha224;
        break;
    case S2N_HASH_SHA256:
        *hash_state = conn->handshake.sha256;
        break;
    case S2N_HASH_SHA384:
        *hash_state = conn->handshake.sha384;
        break;
    case S2N_HASH_SHA512:
        *hash_state = conn->handshake.sha512;
        break;
    case S2N_HASH_MD5_SHA1:
        *hash_state = conn->handshake.md5_sha1;
        break;
    default:
        S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
    }
    return 0;
}
Ejemplo n.º 20
0
int s2n_dh_compute_shared_secret_as_server(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *Yc_in, struct s2n_blob *shared_key)
{
    uint16_t Yc_length;
    struct s2n_blob Yc;
    int shared_key_size;
    BIGNUM *pub_key;

    GUARD(s2n_check_all_dh_params(server_dh_params));

    GUARD(s2n_stuffer_read_uint16(Yc_in, &Yc_length));
    Yc.size = Yc_length;
    Yc.data = s2n_stuffer_raw_read(Yc_in, Yc.size);
    notnull_check(Yc.data);

    pub_key = BN_bin2bn((const unsigned char *)Yc.data, Yc.size, NULL);
    notnull_check(pub_key);
    GUARD(s2n_alloc(shared_key, DH_size(server_dh_params->dh)));

    shared_key_size = DH_compute_key(shared_key->data, pub_key, server_dh_params->dh);
    if (shared_key_size <= 0) {
        BN_free(pub_key);
        S2N_ERROR(S2N_ERR_DH_SHARED_SECRET);
    }

    shared_key->size = shared_key_size;

    BN_free(pub_key);

    return 0;
}
Ejemplo n.º 21
0
static int s2n_evp_hmac_p_hash_init(struct s2n_prf_working_space *ws, s2n_hmac_algorithm alg, struct s2n_blob *secret)
{
    /* Initialize the message digest */
    switch (alg) {
    case S2N_HMAC_SSLv3_MD5:
    case S2N_HMAC_MD5:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_md5();
        break;
    case S2N_HMAC_SSLv3_SHA1:
    case S2N_HMAC_SHA1:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha1();
        break;
    case S2N_HMAC_SHA224:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha224();
        break;
    case S2N_HMAC_SHA256:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha256();
        break;
    case S2N_HMAC_SHA384:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha384();
        break;
    case S2N_HMAC_SHA512:
        ws->tls.p_hash.evp_hmac.evp_digest.md = EVP_sha512();
        break;
    default:
        S2N_ERROR(S2N_ERR_P_HASH_INVALID_ALGORITHM);
    }

    /* Initialize the mac key using the provided secret */
    notnull_check(ws->tls.p_hash.evp_hmac.mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, secret->data, secret->size));

    /* Initialize the message digest context with the above message digest and mac key */
    return s2n_evp_hmac_p_hash_digest_init(ws);
}
Ejemplo n.º 22
0
int s2n_map_lookup(struct s2n_map *map, struct s2n_blob *key, struct s2n_blob *value)
{
    if (!map->immutable) {
        S2N_ERROR(S2N_ERR_MAP_MUTABLE);
    }

    uint32_t slot = s2n_map_slot(map, key);

    while(map->table[slot].key.size) {
        if (key->size != map->table[slot].key.size ||
            memcmp(key->data,  map->table[slot].key.data, key->size)) {
            slot++;
            slot %= map->capacity;
            continue;
        }

        /* We found a match */
        value->data = map->table[slot].value.data;
        value->size = map->table[slot].value.size;

        return 1;
    }

    return 0;
}
Ejemplo n.º 23
0
int s2n_stuffer_skip_read(struct s2n_stuffer *stuffer, uint32_t n)
{
    if (s2n_stuffer_data_available(stuffer) < n) {
        S2N_ERROR(S2N_ERR_STUFFER_OUT_OF_DATA);
    }

    stuffer->read_cursor += n;
    return 0;
}
Ejemplo n.º 24
0
int s2n_set_cipher_as_client(struct s2n_connection *conn, uint8_t wire[S2N_TLS_CIPHER_SUITE_LEN])
{
    /* See if the pending cipher is one we support */
    conn->pending.cipher_suite = s2n_cipher_suite_match(wire);
    if (conn->pending.cipher_suite == NULL) {
        S2N_ERROR(S2N_ERR_CIPHER_NOT_SUPPORTED);
    }

    return 0;
}
Ejemplo n.º 25
0
int s2n_dh_generate_ephemeral_key(struct s2n_dh_params *dh_params)
{
    GUARD(s2n_check_p_g_dh_params(dh_params));

    if (DH_generate_key(dh_params->dh) == 0) {
        S2N_ERROR(S2N_ERR_DH_GENERATING_PARAMETERS);
    }

    return 0;
}
Ejemplo n.º 26
0
static int s2n_drbg_block_encrypt(EVP_CIPHER_CTX *ctx, uint8_t in[S2N_DRBG_BLOCK_SIZE], uint8_t out[S2N_DRBG_BLOCK_SIZE])
{
    int len = S2N_DRBG_BLOCK_SIZE;
    if (EVP_EncryptUpdate(ctx, out, &len, in, S2N_DRBG_BLOCK_SIZE) != 1) {
        S2N_ERROR(S2N_ERR_DRBG);
    }
    eq_check(len, S2N_DRBG_BLOCK_SIZE);

    return 0;
}
Ejemplo n.º 27
0
int s2n_realloc(struct s2n_blob *b, uint32_t size)
{
    if (size == 0) { return s2n_free(b); }

    if (size < b->allocated) { b->size = size; return 0; }

    uint32_t allocate = page_size * ((size + (page_size - 1)) / page_size);
    
    // preventing unsigned overflow occurs at (size + (page_size - 1))
    uint32_t allocate = page_size * (((size - 1) / page_size) + 1);

    void *data;
    if (posix_memalign(&data, page_size, allocate)) {
        S2N_ERROR(S2N_ERR_ALLOC);
    }

    if (b->size) {
        memcpy_check(data, b->data, b->size);
        GUARD(s2n_free(b));
    }

    b->data = data;
    b->size = size;
    b->allocated = allocate;

#ifdef MADV_DONTDUMP
    if (madvise(b->data, size, MADV_DONTDUMP) < 0) {
        GUARD(s2n_free(b));
        S2N_ERROR(S2N_ERR_MADVISE);
    }
#endif
    if (use_mlock == 0) {
        return 0;
    }

    if (mlock(b->data, size) < 0) {
        GUARD(s2n_free(b));
        S2N_ERROR(S2N_ERR_MLOCK);
    }
    b->mlocked = 1;

    return 0;
}
Ejemplo n.º 28
0
int s2n_dh_params_to_p_g_Ys(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *out, struct s2n_blob *output)
{
    GUARD(s2n_check_all_dh_params(server_dh_params));

    const BIGNUM *bn_p = s2n_get_p_dh_param(server_dh_params);
    const BIGNUM *bn_g = s2n_get_g_dh_param(server_dh_params);
    const BIGNUM *bn_Ys = s2n_get_Ys_dh_param(server_dh_params);

    uint16_t p_size = BN_num_bytes(bn_p);
    uint16_t g_size = BN_num_bytes(bn_g);
    uint16_t Ys_size = BN_num_bytes(bn_Ys);
    uint8_t *p;
    uint8_t *g;
    uint8_t *Ys;

    output->data = s2n_stuffer_raw_write(out, 0);
    notnull_check(output->data);

    GUARD(s2n_stuffer_write_uint16(out, p_size));
    p = s2n_stuffer_raw_write(out, p_size);
    notnull_check(p);
    if (BN_bn2bin(bn_p, p) != p_size) {
        S2N_ERROR(S2N_ERR_DH_SERIALIZING);
    }

    GUARD(s2n_stuffer_write_uint16(out, g_size));
    g = s2n_stuffer_raw_write(out, g_size);
    notnull_check(g);
    if (BN_bn2bin(bn_g, g) != g_size) {
        S2N_ERROR(S2N_ERR_DH_SERIALIZING);
    }

    GUARD(s2n_stuffer_write_uint16(out, Ys_size));
    Ys = s2n_stuffer_raw_write(out, Ys_size);
    notnull_check(Ys);
    if (BN_bn2bin(bn_Ys, Ys) != Ys_size) {
        S2N_ERROR(S2N_ERR_DH_SERIALIZING);
    }

    output->size = p_size + 2 + g_size + 2 + Ys_size + 2;

    return 0;
}
Ejemplo n.º 29
0
int s2n_dh_compute_shared_secret_as_client(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *Yc_out, struct s2n_blob *shared_key)
{
    struct s2n_dh_params client_params;
    uint8_t *client_pub_key;
    uint16_t client_pub_key_size;
    int shared_key_size;

    GUARD(s2n_dh_params_check(server_dh_params));
    GUARD(s2n_dh_params_copy(server_dh_params, &client_params));
    GUARD(s2n_dh_generate_ephemeral_key(&client_params));
    GUARD(s2n_alloc(shared_key, DH_size(server_dh_params->dh)));

    const BIGNUM *client_pub_key_bn = s2n_get_Ys_dh_param(&client_params);
    client_pub_key_size = BN_num_bytes(client_pub_key_bn);
    GUARD(s2n_stuffer_write_uint16(Yc_out, client_pub_key_size));
    client_pub_key = s2n_stuffer_raw_write(Yc_out, client_pub_key_size);
    if (client_pub_key == NULL) {
        GUARD(s2n_free(shared_key));
        GUARD(s2n_dh_params_free(&client_params));
        S2N_ERROR(S2N_ERR_DH_WRITING_PUBLIC_KEY);
    }

    if (BN_bn2bin(client_pub_key_bn, client_pub_key) != client_pub_key_size) {
        GUARD(s2n_free(shared_key));
        GUARD(s2n_dh_params_free(&client_params));
        S2N_ERROR(S2N_ERR_DH_COPYING_PUBLIC_KEY);
    }

    /* server_dh_params already validated */
    const BIGNUM *server_pub_key_bn = s2n_get_Ys_dh_param(server_dh_params);
    shared_key_size = DH_compute_key(shared_key->data, server_pub_key_bn, client_params.dh);
    if (shared_key_size < 0) {
        GUARD(s2n_free(shared_key));
        GUARD(s2n_dh_params_free(&client_params));
        S2N_ERROR(S2N_ERR_DH_SHARED_SECRET);
    }

    shared_key->size = shared_key_size;

    GUARD(s2n_dh_params_free(&client_params));

    return 0;
}
Ejemplo n.º 30
0
int s2n_rsa_decrypt(struct s2n_rsa_private_key *key, struct s2n_blob *in, struct s2n_blob *out)
{
    unsigned char intermediate[4096];
    if (s2n_rsa_private_encrypted_size(key) > sizeof(intermediate)) {
        S2N_ERROR(S2N_ERR_NOMEM);
    }

    if (out->size > sizeof(intermediate)) {
        S2N_ERROR(S2N_ERR_NOMEM);
    }

    int r = RSA_private_decrypt(in->size, (unsigned char *)in->data, intermediate, key->rsa, RSA_PKCS1_PADDING);
    GUARD(s2n_constant_time_copy_or_dont(out->data, intermediate, out->size, r != out->size));
    if (r != out->size) {
        S2N_ERROR(S2N_ERR_SIZE_MISMATCH);
    }

    return 0;
}