int aws_cryptosdk_deserialize_frame()

in source/framefmt.c [373:432]


int aws_cryptosdk_deserialize_frame(
    /* out */
    struct aws_cryptosdk_frame *frame,
    size_t *ciphertext_size,
    size_t *plaintext_size,
    /* in */
    struct aws_byte_cursor *ciphertext_buf,
    const struct aws_cryptosdk_alg_properties *alg_props,
    uint64_t max_frame_size) {
    AWS_PRECONDITION(aws_byte_cursor_is_valid(ciphertext_buf));
    AWS_PRECONDITION(aws_cryptosdk_alg_properties_is_valid(alg_props));
    struct aws_cryptosdk_framestate state;
    state.max_frame_size  = max_frame_size;
    state.plaintext_size  = 0;
    state.ciphertext_size = 0;

    state.alg_props = alg_props;
    state.u.cursor  = *ciphertext_buf;

    state.writing   = false;
    state.too_small = false;

    aws_secure_zero(frame, sizeof(*frame));

    int result;

    if (max_frame_size) {
        result = serde_framed(&state, frame);
    } else {
        result = serde_nonframed(&state, frame);
    }

    if (result == AWS_ERROR_SUCCESS && state.too_small) {
        result = AWS_ERROR_SHORT_BUFFER;
    }

    if (state.ciphertext_size > SIZE_MAX || state.plaintext_size > SIZE_MAX) {
        // The ciphertext or plaintext is too large to hold in memory on this platform.
        // This avoids issues with integer truncation resulting in the upper bits of
        // the frame size being ignored on 32-bit platforms.
        result = AWS_CRYPTOSDK_ERR_LIMIT_EXCEEDED;
    }

    *plaintext_size  = state.plaintext_size;
    *ciphertext_size = state.ciphertext_size;

    if (result != AWS_ERROR_SUCCESS) {
        // Don't leak a partially-initialized structure
        aws_secure_zero(frame, sizeof(*frame));
        AWS_POSTCONDITION(aws_byte_cursor_is_valid(ciphertext_buf));
        AWS_POSTCONDITION(aws_cryptosdk_alg_properties_is_valid(alg_props));
        return aws_raise_error(result);
    } else {
        *ciphertext_buf = state.u.cursor;
        AWS_POSTCONDITION(aws_cryptosdk_frame_is_valid(frame));
        AWS_POSTCONDITION(aws_byte_cursor_is_valid(ciphertext_buf));
        AWS_POSTCONDITION(aws_cryptosdk_alg_properties_is_valid(alg_props));
        return AWS_OP_SUCCESS;
    }
}